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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (174) hide show
  1. package/README.md +1 -1
  2. package/package.json +33 -18
  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/get.js +1857 -0
  6. package/pdfjs/dist/index.js +767 -0
  7. package/pdfjs/dist/l10n_utils.js +140 -0
  8. package/{src/shared → pdfjs/dist}/message_handler.js +243 -259
  9. package/{src/display → pdfjs/dist}/network.js +149 -87
  10. package/{src/display/content_disposition.js → pdfjs/dist/network_utils.js} +167 -55
  11. package/{src/display → pdfjs/dist}/node_stream.js +133 -98
  12. package/pdfjs/dist/pdf.js +12778 -0
  13. package/pdfjs/dist/pdf_link_service.js +638 -0
  14. package/pdfjs/dist/pdf_rendering_queue.js +199 -0
  15. package/pdfjs/dist/pdf_thumbnail_viewer.js +819 -0
  16. package/pdfjs/dist/pdf_viewer.js +3598 -0
  17. package/pdfjs/dist/typeof.js +100 -0
  18. package/pdfjs/dist/ui_utils.js +1033 -0
  19. package/{src/shared → pdfjs/dist}/util.js +301 -287
  20. package/pdfjs/dist/worker.js +62813 -0
  21. package/src/vcf-pdf-viewer.js +77 -27
  22. package/theme/lumo/vcf-pdf-viewer-styles.js +1 -1
  23. package/theme/material/vcf-pdf-viewer.js +2 -2
  24. package/src/core/.eslintrc +0 -13
  25. package/src/core/annotation.js +0 -2948
  26. package/src/core/arithmetic_decoder.js +0 -182
  27. package/src/core/ascii_85_stream.js +0 -98
  28. package/src/core/ascii_hex_stream.js +0 -79
  29. package/src/core/base_stream.js +0 -110
  30. package/src/core/bidi.js +0 -438
  31. package/src/core/calibri_factors.js +0 -308
  32. package/src/core/catalog.js +0 -1459
  33. package/src/core/ccitt.js +0 -1062
  34. package/src/core/ccitt_stream.js +0 -60
  35. package/src/core/cff_font.js +0 -116
  36. package/src/core/cff_parser.js +0 -1949
  37. package/src/core/charsets.js +0 -119
  38. package/src/core/chunked_stream.js +0 -557
  39. package/src/core/cmap.js +0 -1039
  40. package/src/core/colorspace.js +0 -1533
  41. package/src/core/core_utils.js +0 -464
  42. package/src/core/crypto.js +0 -1900
  43. package/src/core/decode_stream.js +0 -170
  44. package/src/core/decrypt_stream.js +0 -59
  45. package/src/core/default_appearance.js +0 -99
  46. package/src/core/document.js +0 -1456
  47. package/src/core/encodings.js +0 -301
  48. package/src/core/evaluator.js +0 -4601
  49. package/src/core/file_spec.js +0 -108
  50. package/src/core/flate_stream.js +0 -402
  51. package/src/core/font_renderer.js +0 -882
  52. package/src/core/fonts.js +0 -3260
  53. package/src/core/fonts_utils.js +0 -221
  54. package/src/core/function.js +0 -1257
  55. package/src/core/glyf.js +0 -706
  56. package/src/core/glyphlist.js +0 -4558
  57. package/src/core/helvetica_factors.js +0 -353
  58. package/src/core/image.js +0 -802
  59. package/src/core/image_utils.js +0 -291
  60. package/src/core/jbig2.js +0 -2572
  61. package/src/core/jbig2_stream.js +0 -73
  62. package/src/core/jpeg_stream.js +0 -105
  63. package/src/core/jpg.js +0 -1416
  64. package/src/core/jpx.js +0 -2343
  65. package/src/core/jpx_stream.js +0 -87
  66. package/src/core/liberationsans_widths.js +0 -221
  67. package/src/core/lzw_stream.js +0 -150
  68. package/src/core/metadata_parser.js +0 -146
  69. package/src/core/metrics.js +0 -2970
  70. package/src/core/murmurhash3.js +0 -139
  71. package/src/core/myriadpro_factors.js +0 -290
  72. package/src/core/name_number_tree.js +0 -153
  73. package/src/core/object_loader.js +0 -149
  74. package/src/core/opentype_file_builder.js +0 -154
  75. package/src/core/operator_list.js +0 -734
  76. package/src/core/parser.js +0 -1416
  77. package/src/core/pattern.js +0 -985
  78. package/src/core/pdf_manager.js +0 -217
  79. package/src/core/predictor_stream.js +0 -238
  80. package/src/core/primitives.js +0 -402
  81. package/src/core/ps_parser.js +0 -272
  82. package/src/core/run_length_stream.js +0 -61
  83. package/src/core/segoeui_factors.js +0 -308
  84. package/src/core/standard_fonts.js +0 -817
  85. package/src/core/stream.js +0 -103
  86. package/src/core/struct_tree.js +0 -335
  87. package/src/core/to_unicode_map.js +0 -103
  88. package/src/core/type1_font.js +0 -421
  89. package/src/core/type1_parser.js +0 -776
  90. package/src/core/unicode.js +0 -1649
  91. package/src/core/worker.js +0 -848
  92. package/src/core/worker_stream.js +0 -135
  93. package/src/core/writer.js +0 -278
  94. package/src/core/xfa/bind.js +0 -652
  95. package/src/core/xfa/builder.js +0 -207
  96. package/src/core/xfa/config.js +0 -1926
  97. package/src/core/xfa/connection_set.js +0 -202
  98. package/src/core/xfa/data.js +0 -82
  99. package/src/core/xfa/datasets.js +0 -76
  100. package/src/core/xfa/factory.js +0 -111
  101. package/src/core/xfa/fonts.js +0 -181
  102. package/src/core/xfa/formcalc_lexer.js +0 -385
  103. package/src/core/xfa/formcalc_parser.js +0 -1340
  104. package/src/core/xfa/html_utils.js +0 -639
  105. package/src/core/xfa/layout.js +0 -383
  106. package/src/core/xfa/locale_set.js +0 -345
  107. package/src/core/xfa/namespaces.js +0 -81
  108. package/src/core/xfa/parser.js +0 -184
  109. package/src/core/xfa/setup.js +0 -38
  110. package/src/core/xfa/signature.js +0 -40
  111. package/src/core/xfa/som.js +0 -338
  112. package/src/core/xfa/stylesheet.js +0 -40
  113. package/src/core/xfa/template.js +0 -6260
  114. package/src/core/xfa/text.js +0 -290
  115. package/src/core/xfa/unknown.js +0 -29
  116. package/src/core/xfa/utils.js +0 -217
  117. package/src/core/xfa/xdp.js +0 -59
  118. package/src/core/xfa/xfa_object.js +0 -1130
  119. package/src/core/xfa/xhtml.js +0 -543
  120. package/src/core/xfa_fonts.js +0 -208
  121. package/src/core/xml_parser.js +0 -507
  122. package/src/core/xref.js +0 -899
  123. package/src/display/annotation_layer.js +0 -2107
  124. package/src/display/annotation_storage.js +0 -113
  125. package/src/display/api.js +0 -3292
  126. package/src/display/base_factory.js +0 -180
  127. package/src/display/canvas.js +0 -2828
  128. package/src/display/font_loader.js +0 -484
  129. package/src/display/metadata.js +0 -41
  130. package/src/display/network_utils.js +0 -100
  131. package/src/display/node_utils.js +0 -83
  132. package/src/display/optional_content_config.js +0 -189
  133. package/src/display/pattern_helper.js +0 -659
  134. package/src/display/svg.js +0 -1709
  135. package/src/display/text_layer.js +0 -847
  136. package/src/display/transport_stream.js +0 -303
  137. package/src/display/worker_options.js +0 -40
  138. package/src/display/xfa_layer.js +0 -204
  139. package/src/doc_helper.js +0 -25
  140. package/src/images/logo.svg +0 -41
  141. package/src/interfaces.js +0 -169
  142. package/src/license_header.js +0 -14
  143. package/src/license_header_libre.js +0 -21
  144. package/src/pdf.image_decoders.js +0 -46
  145. package/src/pdf.js +0 -146
  146. package/src/pdf.sandbox.external.js +0 -181
  147. package/src/pdf.sandbox.js +0 -151
  148. package/src/pdf.scripting.js +0 -25
  149. package/src/pdf.worker.entry.js +0 -19
  150. package/src/pdf.worker.js +0 -23
  151. package/src/scripting_api/aform.js +0 -608
  152. package/src/scripting_api/app.js +0 -621
  153. package/src/scripting_api/color.js +0 -129
  154. package/src/scripting_api/common.js +0 -58
  155. package/src/scripting_api/console.js +0 -38
  156. package/src/scripting_api/constants.js +0 -208
  157. package/src/scripting_api/doc.js +0 -1195
  158. package/src/scripting_api/error.js +0 -23
  159. package/src/scripting_api/event.js +0 -232
  160. package/src/scripting_api/field.js +0 -620
  161. package/src/scripting_api/fullscreen.js +0 -145
  162. package/src/scripting_api/initialization.js +0 -223
  163. package/src/scripting_api/pdf_object.js +0 -24
  164. package/src/scripting_api/print_params.js +0 -146
  165. package/src/scripting_api/proxy.js +0 -139
  166. package/src/scripting_api/thermometer.js +0 -69
  167. package/src/scripting_api/util.js +0 -581
  168. package/src/shared/.eslintrc +0 -13
  169. package/src/shared/cffStandardStrings.js +0 -311
  170. package/src/shared/compatibility.js +0 -114
  171. package/src/shared/fonts_utils.js +0 -429
  172. package/src/shared/is_node.js +0 -27
  173. package/src/shared/scripting_utils.js +0 -85
  174. package/src/worker_loader.js +0 -32
@@ -1,1709 +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
- /* globals __non_webpack_require__ */
16
-
17
- import {
18
- createObjectURL,
19
- FONT_IDENTITY_MATRIX,
20
- IDENTITY_MATRIX,
21
- ImageKind,
22
- isNum,
23
- OPS,
24
- TextRenderingMode,
25
- unreachable,
26
- Util,
27
- warn,
28
- } from "../shared/util.js";
29
- import { DOMSVGFactory } from "./display_utils.js";
30
- import { isNodeJS } from "../shared/is_node.js";
31
-
32
- /** @type {any} */
33
- let SVGGraphics = class {
34
- constructor() {
35
- unreachable("Not implemented: SVGGraphics");
36
- }
37
- };
38
-
39
- if (
40
- typeof PDFJSDev === "undefined" ||
41
- PDFJSDev.test("!PRODUCTION || GENERIC")
42
- ) {
43
- const SVG_DEFAULTS = {
44
- fontStyle: "normal",
45
- fontWeight: "normal",
46
- fillColor: "#000000",
47
- };
48
- const XML_NS = "http://www.w3.org/XML/1998/namespace";
49
- const XLINK_NS = "http://www.w3.org/1999/xlink";
50
- const LINE_CAP_STYLES = ["butt", "round", "square"];
51
- const LINE_JOIN_STYLES = ["miter", "round", "bevel"];
52
-
53
- const convertImgDataToPng = (function () {
54
- const PNG_HEADER = new Uint8Array([
55
- 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a,
56
- ]);
57
- const CHUNK_WRAPPER_SIZE = 12;
58
-
59
- const crcTable = new Int32Array(256);
60
- for (let i = 0; i < 256; i++) {
61
- let c = i;
62
- for (let h = 0; h < 8; h++) {
63
- if (c & 1) {
64
- c = 0xedb88320 ^ ((c >> 1) & 0x7fffffff);
65
- } else {
66
- c = (c >> 1) & 0x7fffffff;
67
- }
68
- }
69
- crcTable[i] = c;
70
- }
71
-
72
- function crc32(data, start, end) {
73
- let crc = -1;
74
- for (let i = start; i < end; i++) {
75
- const a = (crc ^ data[i]) & 0xff;
76
- const b = crcTable[a];
77
- crc = (crc >>> 8) ^ b;
78
- }
79
- return crc ^ -1;
80
- }
81
-
82
- function writePngChunk(type, body, data, offset) {
83
- let p = offset;
84
- const len = body.length;
85
-
86
- data[p] = (len >> 24) & 0xff;
87
- data[p + 1] = (len >> 16) & 0xff;
88
- data[p + 2] = (len >> 8) & 0xff;
89
- data[p + 3] = len & 0xff;
90
- p += 4;
91
-
92
- data[p] = type.charCodeAt(0) & 0xff;
93
- data[p + 1] = type.charCodeAt(1) & 0xff;
94
- data[p + 2] = type.charCodeAt(2) & 0xff;
95
- data[p + 3] = type.charCodeAt(3) & 0xff;
96
- p += 4;
97
-
98
- data.set(body, p);
99
- p += body.length;
100
-
101
- const crc = crc32(data, offset + 4, p);
102
- data[p] = (crc >> 24) & 0xff;
103
- data[p + 1] = (crc >> 16) & 0xff;
104
- data[p + 2] = (crc >> 8) & 0xff;
105
- data[p + 3] = crc & 0xff;
106
- }
107
-
108
- function adler32(data, start, end) {
109
- let a = 1;
110
- let b = 0;
111
- for (let i = start; i < end; ++i) {
112
- a = (a + (data[i] & 0xff)) % 65521;
113
- b = (b + a) % 65521;
114
- }
115
- return (b << 16) | a;
116
- }
117
-
118
- /**
119
- * @param {Uint8Array} literals The input data.
120
- * @returns {Uint8Array} The DEFLATE-compressed data stream in zlib format.
121
- * This is the required format for compressed streams in the PNG format:
122
- * http://www.libpng.org/pub/png/spec/1.2/PNG-Compression.html
123
- */
124
- function deflateSync(literals) {
125
- if (!isNodeJS) {
126
- // zlib is certainly not available outside of Node.js. We can either use
127
- // the pako library for client-side DEFLATE compression, or use the
128
- // canvas API of the browser to obtain a more optimal PNG file.
129
- return deflateSyncUncompressed(literals);
130
- }
131
- try {
132
- // NOTE: This implementation is far from perfect, but already way better
133
- // than not applying any compression.
134
- //
135
- // A better algorithm will try to choose a good predictor/filter and
136
- // then choose a suitable zlib compression strategy (e.g. 3,Z_RLE).
137
- //
138
- // Node v0.11.12 zlib.deflateSync is introduced (and returns a Buffer).
139
- // Node v3.0.0 Buffer inherits from Uint8Array.
140
- // Node v8.0.0 zlib.deflateSync accepts Uint8Array as input.
141
- let input;
142
- // eslint-disable-next-line no-undef
143
- if (parseInt(process.versions.node) >= 8) {
144
- input = literals;
145
- } else {
146
- // eslint-disable-next-line no-undef
147
- input = Buffer.from(literals);
148
- }
149
- const output = __non_webpack_require__("zlib").deflateSync(input, {
150
- level: 9,
151
- });
152
- return output instanceof Uint8Array ? output : new Uint8Array(output);
153
- } catch (e) {
154
- warn(
155
- "Not compressing PNG because zlib.deflateSync is unavailable: " + e
156
- );
157
- }
158
-
159
- return deflateSyncUncompressed(literals);
160
- }
161
-
162
- // An implementation of DEFLATE with compression level 0 (Z_NO_COMPRESSION).
163
- function deflateSyncUncompressed(literals) {
164
- let len = literals.length;
165
- const maxBlockLength = 0xffff;
166
-
167
- const deflateBlocks = Math.ceil(len / maxBlockLength);
168
- const idat = new Uint8Array(2 + len + deflateBlocks * 5 + 4);
169
- let pi = 0;
170
- idat[pi++] = 0x78; // compression method and flags
171
- idat[pi++] = 0x9c; // flags
172
-
173
- let pos = 0;
174
- while (len > maxBlockLength) {
175
- // writing non-final DEFLATE blocks type 0 and length of 65535
176
- idat[pi++] = 0x00;
177
- idat[pi++] = 0xff;
178
- idat[pi++] = 0xff;
179
- idat[pi++] = 0x00;
180
- idat[pi++] = 0x00;
181
- idat.set(literals.subarray(pos, pos + maxBlockLength), pi);
182
- pi += maxBlockLength;
183
- pos += maxBlockLength;
184
- len -= maxBlockLength;
185
- }
186
-
187
- // writing non-final DEFLATE blocks type 0
188
- idat[pi++] = 0x01;
189
- idat[pi++] = len & 0xff;
190
- idat[pi++] = (len >> 8) & 0xff;
191
- idat[pi++] = ~len & 0xffff & 0xff;
192
- idat[pi++] = ((~len & 0xffff) >> 8) & 0xff;
193
- idat.set(literals.subarray(pos), pi);
194
- pi += literals.length - pos;
195
-
196
- const adler = adler32(literals, 0, literals.length); // checksum
197
- idat[pi++] = (adler >> 24) & 0xff;
198
- idat[pi++] = (adler >> 16) & 0xff;
199
- idat[pi++] = (adler >> 8) & 0xff;
200
- idat[pi++] = adler & 0xff;
201
- return idat;
202
- }
203
-
204
- function encode(imgData, kind, forceDataSchema, isMask) {
205
- const width = imgData.width;
206
- const height = imgData.height;
207
- let bitDepth, colorType, lineSize;
208
- const bytes = imgData.data;
209
-
210
- switch (kind) {
211
- case ImageKind.GRAYSCALE_1BPP:
212
- colorType = 0;
213
- bitDepth = 1;
214
- lineSize = (width + 7) >> 3;
215
- break;
216
- case ImageKind.RGB_24BPP:
217
- colorType = 2;
218
- bitDepth = 8;
219
- lineSize = width * 3;
220
- break;
221
- case ImageKind.RGBA_32BPP:
222
- colorType = 6;
223
- bitDepth = 8;
224
- lineSize = width * 4;
225
- break;
226
- default:
227
- throw new Error("invalid format");
228
- }
229
-
230
- // prefix every row with predictor 0
231
- const literals = new Uint8Array((1 + lineSize) * height);
232
- let offsetLiterals = 0,
233
- offsetBytes = 0;
234
- for (let y = 0; y < height; ++y) {
235
- literals[offsetLiterals++] = 0; // no prediction
236
- literals.set(
237
- bytes.subarray(offsetBytes, offsetBytes + lineSize),
238
- offsetLiterals
239
- );
240
- offsetBytes += lineSize;
241
- offsetLiterals += lineSize;
242
- }
243
-
244
- if (kind === ImageKind.GRAYSCALE_1BPP && isMask) {
245
- // inverting for image masks
246
- offsetLiterals = 0;
247
- for (let y = 0; y < height; y++) {
248
- offsetLiterals++; // skipping predictor
249
- for (let i = 0; i < lineSize; i++) {
250
- literals[offsetLiterals++] ^= 0xff;
251
- }
252
- }
253
- }
254
-
255
- const ihdr = new Uint8Array([
256
- (width >> 24) & 0xff,
257
- (width >> 16) & 0xff,
258
- (width >> 8) & 0xff,
259
- width & 0xff,
260
- (height >> 24) & 0xff,
261
- (height >> 16) & 0xff,
262
- (height >> 8) & 0xff,
263
- height & 0xff,
264
- bitDepth, // bit depth
265
- colorType, // color type
266
- 0x00, // compression method
267
- 0x00, // filter method
268
- 0x00, // interlace method
269
- ]);
270
- const idat = deflateSync(literals);
271
-
272
- // PNG consists of: header, IHDR+data, IDAT+data, and IEND.
273
- const pngLength =
274
- PNG_HEADER.length + CHUNK_WRAPPER_SIZE * 3 + ihdr.length + idat.length;
275
- const data = new Uint8Array(pngLength);
276
- let offset = 0;
277
- data.set(PNG_HEADER, offset);
278
- offset += PNG_HEADER.length;
279
- writePngChunk("IHDR", ihdr, data, offset);
280
- offset += CHUNK_WRAPPER_SIZE + ihdr.length;
281
- writePngChunk("IDATA", idat, data, offset);
282
- offset += CHUNK_WRAPPER_SIZE + idat.length;
283
- writePngChunk("IEND", new Uint8Array(0), data, offset);
284
-
285
- return createObjectURL(data, "image/png", forceDataSchema);
286
- }
287
-
288
- // eslint-disable-next-line no-shadow
289
- return function convertImgDataToPng(imgData, forceDataSchema, isMask) {
290
- const kind =
291
- imgData.kind === undefined ? ImageKind.GRAYSCALE_1BPP : imgData.kind;
292
- return encode(imgData, kind, forceDataSchema, isMask);
293
- };
294
- })();
295
-
296
- class SVGExtraState {
297
- constructor() {
298
- this.fontSizeScale = 1;
299
- this.fontWeight = SVG_DEFAULTS.fontWeight;
300
- this.fontSize = 0;
301
-
302
- this.textMatrix = IDENTITY_MATRIX;
303
- this.fontMatrix = FONT_IDENTITY_MATRIX;
304
- this.leading = 0;
305
- this.textRenderingMode = TextRenderingMode.FILL;
306
- this.textMatrixScale = 1;
307
-
308
- // Current point (in user coordinates)
309
- this.x = 0;
310
- this.y = 0;
311
-
312
- // Start of text line (in text coordinates)
313
- this.lineX = 0;
314
- this.lineY = 0;
315
-
316
- // Character and word spacing
317
- this.charSpacing = 0;
318
- this.wordSpacing = 0;
319
- this.textHScale = 1;
320
- this.textRise = 0;
321
-
322
- // Default foreground and background colors
323
- this.fillColor = SVG_DEFAULTS.fillColor;
324
- this.strokeColor = "#000000";
325
-
326
- this.fillAlpha = 1;
327
- this.strokeAlpha = 1;
328
- this.lineWidth = 1;
329
- this.lineJoin = "";
330
- this.lineCap = "";
331
- this.miterLimit = 0;
332
-
333
- this.dashArray = [];
334
- this.dashPhase = 0;
335
-
336
- this.dependencies = [];
337
-
338
- // Clipping
339
- this.activeClipUrl = null;
340
- this.clipGroup = null;
341
-
342
- this.maskId = "";
343
- }
344
-
345
- clone() {
346
- return Object.create(this);
347
- }
348
-
349
- setCurrentPoint(x, y) {
350
- this.x = x;
351
- this.y = y;
352
- }
353
- }
354
-
355
- // eslint-disable-next-line no-inner-declarations
356
- function opListToTree(opList) {
357
- let opTree = [];
358
- const tmp = [];
359
-
360
- for (const opListElement of opList) {
361
- if (opListElement.fn === "save") {
362
- opTree.push({ fnId: 92, fn: "group", items: [] });
363
- tmp.push(opTree);
364
- opTree = opTree[opTree.length - 1].items;
365
- continue;
366
- }
367
-
368
- if (opListElement.fn === "restore") {
369
- opTree = tmp.pop();
370
- } else {
371
- opTree.push(opListElement);
372
- }
373
- }
374
- return opTree;
375
- }
376
-
377
- /**
378
- * Format a float number as a string.
379
- *
380
- * @param value {number} - The float number to format.
381
- * @returns {string}
382
- */
383
- // eslint-disable-next-line no-inner-declarations
384
- function pf(value) {
385
- if (Number.isInteger(value)) {
386
- return value.toString();
387
- }
388
- const s = value.toFixed(10);
389
- let i = s.length - 1;
390
- if (s[i] !== "0") {
391
- return s;
392
- }
393
-
394
- // Remove trailing zeros.
395
- do {
396
- i--;
397
- } while (s[i] === "0");
398
- return s.substring(0, s[i] === "." ? i : i + 1);
399
- }
400
-
401
- /**
402
- * Format a transform matrix as a string. The standard rotation, scale and
403
- * translation matrices are replaced by their shorter forms, and for
404
- * identity matrices an empty string is returned to save memory.
405
- *
406
- * @param m {Array} - The transform matrix to format.
407
- * @returns {string}
408
- */
409
- // eslint-disable-next-line no-inner-declarations
410
- function pm(m) {
411
- if (m[4] === 0 && m[5] === 0) {
412
- if (m[1] === 0 && m[2] === 0) {
413
- if (m[0] === 1 && m[3] === 1) {
414
- return "";
415
- }
416
- return `scale(${pf(m[0])} ${pf(m[3])})`;
417
- }
418
- if (m[0] === m[3] && m[1] === -m[2]) {
419
- const a = (Math.acos(m[0]) * 180) / Math.PI;
420
- return `rotate(${pf(a)})`;
421
- }
422
- } else {
423
- if (m[0] === 1 && m[1] === 0 && m[2] === 0 && m[3] === 1) {
424
- return `translate(${pf(m[4])} ${pf(m[5])})`;
425
- }
426
- }
427
- return (
428
- `matrix(${pf(m[0])} ${pf(m[1])} ${pf(m[2])} ${pf(m[3])} ${pf(m[4])} ` +
429
- `${pf(m[5])})`
430
- );
431
- }
432
-
433
- // The counts below are relevant for all pages, so they have to be global
434
- // instead of being members of `SVGGraphics` (which is recreated for
435
- // each page).
436
- let clipCount = 0;
437
- let maskCount = 0;
438
- let shadingCount = 0;
439
-
440
- SVGGraphics = class {
441
- constructor(commonObjs, objs, forceDataSchema = false) {
442
- this.svgFactory = new DOMSVGFactory();
443
-
444
- this.current = new SVGExtraState();
445
- this.transformMatrix = IDENTITY_MATRIX; // Graphics state matrix
446
- this.transformStack = [];
447
- this.extraStack = [];
448
- this.commonObjs = commonObjs;
449
- this.objs = objs;
450
- this.pendingClip = null;
451
- this.pendingEOFill = false;
452
-
453
- this.embedFonts = false;
454
- this.embeddedFonts = Object.create(null);
455
- this.cssStyle = null;
456
- this.forceDataSchema = !!forceDataSchema;
457
-
458
- // In `src/shared/util.js` the operator names are mapped to IDs.
459
- // The list below represents the reverse of that, i.e., it maps IDs
460
- // to operator names.
461
- this._operatorIdMapping = [];
462
- for (const op in OPS) {
463
- this._operatorIdMapping[OPS[op]] = op;
464
- }
465
- }
466
-
467
- save() {
468
- this.transformStack.push(this.transformMatrix);
469
- const old = this.current;
470
- this.extraStack.push(old);
471
- this.current = old.clone();
472
- }
473
-
474
- restore() {
475
- this.transformMatrix = this.transformStack.pop();
476
- this.current = this.extraStack.pop();
477
- this.pendingClip = null;
478
- this.tgrp = null;
479
- }
480
-
481
- group(items) {
482
- this.save();
483
- this.executeOpTree(items);
484
- this.restore();
485
- }
486
-
487
- loadDependencies(operatorList) {
488
- const fnArray = operatorList.fnArray;
489
- const argsArray = operatorList.argsArray;
490
-
491
- for (let i = 0, ii = fnArray.length; i < ii; i++) {
492
- if (fnArray[i] !== OPS.dependency) {
493
- continue;
494
- }
495
-
496
- for (const obj of argsArray[i]) {
497
- const objsPool = obj.startsWith("g_") ? this.commonObjs : this.objs;
498
- const promise = new Promise(resolve => {
499
- objsPool.get(obj, resolve);
500
- });
501
- this.current.dependencies.push(promise);
502
- }
503
- }
504
- return Promise.all(this.current.dependencies);
505
- }
506
-
507
- transform(a, b, c, d, e, f) {
508
- const transformMatrix = [a, b, c, d, e, f];
509
- this.transformMatrix = Util.transform(
510
- this.transformMatrix,
511
- transformMatrix
512
- );
513
- this.tgrp = null;
514
- }
515
-
516
- getSVG(operatorList, viewport) {
517
- this.viewport = viewport;
518
-
519
- const svgElement = this._initialize(viewport);
520
- return this.loadDependencies(operatorList).then(() => {
521
- this.transformMatrix = IDENTITY_MATRIX;
522
- this.executeOpTree(this.convertOpList(operatorList));
523
- return svgElement;
524
- });
525
- }
526
-
527
- convertOpList(operatorList) {
528
- const operatorIdMapping = this._operatorIdMapping;
529
- const argsArray = operatorList.argsArray;
530
- const fnArray = operatorList.fnArray;
531
- const opList = [];
532
- for (let i = 0, ii = fnArray.length; i < ii; i++) {
533
- const fnId = fnArray[i];
534
- opList.push({
535
- fnId,
536
- fn: operatorIdMapping[fnId],
537
- args: argsArray[i],
538
- });
539
- }
540
- return opListToTree(opList);
541
- }
542
-
543
- executeOpTree(opTree) {
544
- for (const opTreeElement of opTree) {
545
- const fn = opTreeElement.fn;
546
- const fnId = opTreeElement.fnId;
547
- const args = opTreeElement.args;
548
-
549
- switch (fnId | 0) {
550
- case OPS.beginText:
551
- this.beginText();
552
- break;
553
- case OPS.dependency:
554
- // Handled in `loadDependencies`, so no warning should be shown.
555
- break;
556
- case OPS.setLeading:
557
- this.setLeading(args);
558
- break;
559
- case OPS.setLeadingMoveText:
560
- this.setLeadingMoveText(args[0], args[1]);
561
- break;
562
- case OPS.setFont:
563
- this.setFont(args);
564
- break;
565
- case OPS.showText:
566
- this.showText(args[0]);
567
- break;
568
- case OPS.showSpacedText:
569
- this.showText(args[0]);
570
- break;
571
- case OPS.endText:
572
- this.endText();
573
- break;
574
- case OPS.moveText:
575
- this.moveText(args[0], args[1]);
576
- break;
577
- case OPS.setCharSpacing:
578
- this.setCharSpacing(args[0]);
579
- break;
580
- case OPS.setWordSpacing:
581
- this.setWordSpacing(args[0]);
582
- break;
583
- case OPS.setHScale:
584
- this.setHScale(args[0]);
585
- break;
586
- case OPS.setTextMatrix:
587
- this.setTextMatrix(
588
- args[0],
589
- args[1],
590
- args[2],
591
- args[3],
592
- args[4],
593
- args[5]
594
- );
595
- break;
596
- case OPS.setTextRise:
597
- this.setTextRise(args[0]);
598
- break;
599
- case OPS.setTextRenderingMode:
600
- this.setTextRenderingMode(args[0]);
601
- break;
602
- case OPS.setLineWidth:
603
- this.setLineWidth(args[0]);
604
- break;
605
- case OPS.setLineJoin:
606
- this.setLineJoin(args[0]);
607
- break;
608
- case OPS.setLineCap:
609
- this.setLineCap(args[0]);
610
- break;
611
- case OPS.setMiterLimit:
612
- this.setMiterLimit(args[0]);
613
- break;
614
- case OPS.setFillRGBColor:
615
- this.setFillRGBColor(args[0], args[1], args[2]);
616
- break;
617
- case OPS.setStrokeRGBColor:
618
- this.setStrokeRGBColor(args[0], args[1], args[2]);
619
- break;
620
- case OPS.setStrokeColorN:
621
- this.setStrokeColorN(args);
622
- break;
623
- case OPS.setFillColorN:
624
- this.setFillColorN(args);
625
- break;
626
- case OPS.shadingFill:
627
- this.shadingFill(args[0]);
628
- break;
629
- case OPS.setDash:
630
- this.setDash(args[0], args[1]);
631
- break;
632
- case OPS.setRenderingIntent:
633
- this.setRenderingIntent(args[0]);
634
- break;
635
- case OPS.setFlatness:
636
- this.setFlatness(args[0]);
637
- break;
638
- case OPS.setGState:
639
- this.setGState(args[0]);
640
- break;
641
- case OPS.fill:
642
- this.fill();
643
- break;
644
- case OPS.eoFill:
645
- this.eoFill();
646
- break;
647
- case OPS.stroke:
648
- this.stroke();
649
- break;
650
- case OPS.fillStroke:
651
- this.fillStroke();
652
- break;
653
- case OPS.eoFillStroke:
654
- this.eoFillStroke();
655
- break;
656
- case OPS.clip:
657
- this.clip("nonzero");
658
- break;
659
- case OPS.eoClip:
660
- this.clip("evenodd");
661
- break;
662
- case OPS.paintSolidColorImageMask:
663
- this.paintSolidColorImageMask();
664
- break;
665
- case OPS.paintImageXObject:
666
- this.paintImageXObject(args[0]);
667
- break;
668
- case OPS.paintInlineImageXObject:
669
- this.paintInlineImageXObject(args[0]);
670
- break;
671
- case OPS.paintImageMaskXObject:
672
- this.paintImageMaskXObject(args[0]);
673
- break;
674
- case OPS.paintFormXObjectBegin:
675
- this.paintFormXObjectBegin(args[0], args[1]);
676
- break;
677
- case OPS.paintFormXObjectEnd:
678
- this.paintFormXObjectEnd();
679
- break;
680
- case OPS.closePath:
681
- this.closePath();
682
- break;
683
- case OPS.closeStroke:
684
- this.closeStroke();
685
- break;
686
- case OPS.closeFillStroke:
687
- this.closeFillStroke();
688
- break;
689
- case OPS.closeEOFillStroke:
690
- this.closeEOFillStroke();
691
- break;
692
- case OPS.nextLine:
693
- this.nextLine();
694
- break;
695
- case OPS.transform:
696
- this.transform(
697
- args[0],
698
- args[1],
699
- args[2],
700
- args[3],
701
- args[4],
702
- args[5]
703
- );
704
- break;
705
- case OPS.constructPath:
706
- this.constructPath(args[0], args[1]);
707
- break;
708
- case OPS.endPath:
709
- this.endPath();
710
- break;
711
- case 92:
712
- this.group(opTreeElement.items);
713
- break;
714
- default:
715
- warn(`Unimplemented operator ${fn}`);
716
- break;
717
- }
718
- }
719
- }
720
-
721
- setWordSpacing(wordSpacing) {
722
- this.current.wordSpacing = wordSpacing;
723
- }
724
-
725
- setCharSpacing(charSpacing) {
726
- this.current.charSpacing = charSpacing;
727
- }
728
-
729
- nextLine() {
730
- this.moveText(0, this.current.leading);
731
- }
732
-
733
- setTextMatrix(a, b, c, d, e, f) {
734
- const current = this.current;
735
- current.textMatrix = current.lineMatrix = [a, b, c, d, e, f];
736
- current.textMatrixScale = Math.hypot(a, b);
737
-
738
- current.x = current.lineX = 0;
739
- current.y = current.lineY = 0;
740
-
741
- current.xcoords = [];
742
- current.ycoords = [];
743
- current.tspan = this.svgFactory.createElement("svg:tspan");
744
- current.tspan.setAttributeNS(null, "font-family", current.fontFamily);
745
- current.tspan.setAttributeNS(
746
- null,
747
- "font-size",
748
- `${pf(current.fontSize)}px`
749
- );
750
- current.tspan.setAttributeNS(null, "y", pf(-current.y));
751
-
752
- current.txtElement = this.svgFactory.createElement("svg:text");
753
- current.txtElement.appendChild(current.tspan);
754
- }
755
-
756
- beginText() {
757
- const current = this.current;
758
- current.x = current.lineX = 0;
759
- current.y = current.lineY = 0;
760
- current.textMatrix = IDENTITY_MATRIX;
761
- current.lineMatrix = IDENTITY_MATRIX;
762
- current.textMatrixScale = 1;
763
- current.tspan = this.svgFactory.createElement("svg:tspan");
764
- current.txtElement = this.svgFactory.createElement("svg:text");
765
- current.txtgrp = this.svgFactory.createElement("svg:g");
766
- current.xcoords = [];
767
- current.ycoords = [];
768
- }
769
-
770
- moveText(x, y) {
771
- const current = this.current;
772
- current.x = current.lineX += x;
773
- current.y = current.lineY += y;
774
-
775
- current.xcoords = [];
776
- current.ycoords = [];
777
- current.tspan = this.svgFactory.createElement("svg:tspan");
778
- current.tspan.setAttributeNS(null, "font-family", current.fontFamily);
779
- current.tspan.setAttributeNS(
780
- null,
781
- "font-size",
782
- `${pf(current.fontSize)}px`
783
- );
784
- current.tspan.setAttributeNS(null, "y", pf(-current.y));
785
- }
786
-
787
- showText(glyphs) {
788
- const current = this.current;
789
- const font = current.font;
790
- const fontSize = current.fontSize;
791
- if (fontSize === 0) {
792
- return;
793
- }
794
-
795
- const fontSizeScale = current.fontSizeScale;
796
- const charSpacing = current.charSpacing;
797
- const wordSpacing = current.wordSpacing;
798
- const fontDirection = current.fontDirection;
799
- const textHScale = current.textHScale * fontDirection;
800
- const vertical = font.vertical;
801
- const spacingDir = vertical ? 1 : -1;
802
- const defaultVMetrics = font.defaultVMetrics;
803
- const widthAdvanceScale = fontSize * current.fontMatrix[0];
804
-
805
- let x = 0;
806
- for (const glyph of glyphs) {
807
- if (glyph === null) {
808
- // Word break
809
- x += fontDirection * wordSpacing;
810
- continue;
811
- } else if (isNum(glyph)) {
812
- x += (spacingDir * glyph * fontSize) / 1000;
813
- continue;
814
- }
815
-
816
- const spacing = (glyph.isSpace ? wordSpacing : 0) + charSpacing;
817
- const character = glyph.fontChar;
818
- let scaledX, scaledY;
819
- let width = glyph.width;
820
- if (vertical) {
821
- let vx;
822
- const vmetric = glyph.vmetric || defaultVMetrics;
823
- vx = glyph.vmetric ? vmetric[1] : width * 0.5;
824
- vx = -vx * widthAdvanceScale;
825
- const vy = vmetric[2] * widthAdvanceScale;
826
-
827
- width = vmetric ? -vmetric[0] : width;
828
- scaledX = vx / fontSizeScale;
829
- scaledY = (x + vy) / fontSizeScale;
830
- } else {
831
- scaledX = x / fontSizeScale;
832
- scaledY = 0;
833
- }
834
-
835
- if (glyph.isInFont || font.missingFile) {
836
- current.xcoords.push(current.x + scaledX);
837
- if (vertical) {
838
- current.ycoords.push(-current.y + scaledY);
839
- }
840
- current.tspan.textContent += character;
841
- } else {
842
- // TODO: To assist with text selection, we should replace the missing
843
- // character with a space character if charWidth is not zero.
844
- // But we cannot just do "character = ' '", because the ' ' character
845
- // might actually map to a different glyph.
846
- }
847
-
848
- let charWidth;
849
- if (vertical) {
850
- charWidth = width * widthAdvanceScale - spacing * fontDirection;
851
- } else {
852
- charWidth = width * widthAdvanceScale + spacing * fontDirection;
853
- }
854
-
855
- x += charWidth;
856
- }
857
- current.tspan.setAttributeNS(
858
- null,
859
- "x",
860
- current.xcoords.map(pf).join(" ")
861
- );
862
- if (vertical) {
863
- current.tspan.setAttributeNS(
864
- null,
865
- "y",
866
- current.ycoords.map(pf).join(" ")
867
- );
868
- } else {
869
- current.tspan.setAttributeNS(null, "y", pf(-current.y));
870
- }
871
-
872
- if (vertical) {
873
- current.y -= x;
874
- } else {
875
- current.x += x * textHScale;
876
- }
877
-
878
- current.tspan.setAttributeNS(null, "font-family", current.fontFamily);
879
- current.tspan.setAttributeNS(
880
- null,
881
- "font-size",
882
- `${pf(current.fontSize)}px`
883
- );
884
- if (current.fontStyle !== SVG_DEFAULTS.fontStyle) {
885
- current.tspan.setAttributeNS(null, "font-style", current.fontStyle);
886
- }
887
- if (current.fontWeight !== SVG_DEFAULTS.fontWeight) {
888
- current.tspan.setAttributeNS(null, "font-weight", current.fontWeight);
889
- }
890
-
891
- const fillStrokeMode =
892
- current.textRenderingMode & TextRenderingMode.FILL_STROKE_MASK;
893
- if (
894
- fillStrokeMode === TextRenderingMode.FILL ||
895
- fillStrokeMode === TextRenderingMode.FILL_STROKE
896
- ) {
897
- if (current.fillColor !== SVG_DEFAULTS.fillColor) {
898
- current.tspan.setAttributeNS(null, "fill", current.fillColor);
899
- }
900
- if (current.fillAlpha < 1) {
901
- current.tspan.setAttributeNS(null, "fill-opacity", current.fillAlpha);
902
- }
903
- } else if (current.textRenderingMode === TextRenderingMode.ADD_TO_PATH) {
904
- // Workaround for Firefox: We must set fill="transparent" because
905
- // fill="none" would generate an empty clipping path.
906
- current.tspan.setAttributeNS(null, "fill", "transparent");
907
- } else {
908
- current.tspan.setAttributeNS(null, "fill", "none");
909
- }
910
-
911
- if (
912
- fillStrokeMode === TextRenderingMode.STROKE ||
913
- fillStrokeMode === TextRenderingMode.FILL_STROKE
914
- ) {
915
- const lineWidthScale = 1 / (current.textMatrixScale || 1);
916
- this._setStrokeAttributes(current.tspan, lineWidthScale);
917
- }
918
-
919
- // Include the text rise in the text matrix since the `pm` function
920
- // creates the SVG element's `translate` entry (work on a copy to avoid
921
- // altering the original text matrix).
922
- let textMatrix = current.textMatrix;
923
- if (current.textRise !== 0) {
924
- textMatrix = textMatrix.slice();
925
- textMatrix[5] += current.textRise;
926
- }
927
-
928
- current.txtElement.setAttributeNS(
929
- null,
930
- "transform",
931
- `${pm(textMatrix)} scale(${pf(textHScale)}, -1)`
932
- );
933
- current.txtElement.setAttributeNS(XML_NS, "xml:space", "preserve");
934
- current.txtElement.appendChild(current.tspan);
935
- current.txtgrp.appendChild(current.txtElement);
936
-
937
- this._ensureTransformGroup().appendChild(current.txtElement);
938
- }
939
-
940
- setLeadingMoveText(x, y) {
941
- this.setLeading(-y);
942
- this.moveText(x, y);
943
- }
944
-
945
- addFontStyle(fontObj) {
946
- if (!fontObj.data) {
947
- throw new Error(
948
- "addFontStyle: No font data available, " +
949
- 'ensure that the "fontExtraProperties" API parameter is set.'
950
- );
951
- }
952
- if (!this.cssStyle) {
953
- this.cssStyle = this.svgFactory.createElement("svg:style");
954
- this.cssStyle.setAttributeNS(null, "type", "text/css");
955
- this.defs.appendChild(this.cssStyle);
956
- }
957
-
958
- const url = createObjectURL(
959
- fontObj.data,
960
- fontObj.mimetype,
961
- this.forceDataSchema
962
- );
963
- this.cssStyle.textContent +=
964
- `@font-face { font-family: "${fontObj.loadedName}";` +
965
- ` src: url(${url}); }\n`;
966
- }
967
-
968
- setFont(details) {
969
- const current = this.current;
970
- const fontObj = this.commonObjs.get(details[0]);
971
- let size = details[1];
972
- current.font = fontObj;
973
-
974
- if (
975
- this.embedFonts &&
976
- !fontObj.missingFile &&
977
- !this.embeddedFonts[fontObj.loadedName]
978
- ) {
979
- this.addFontStyle(fontObj);
980
- this.embeddedFonts[fontObj.loadedName] = fontObj;
981
- }
982
- current.fontMatrix = fontObj.fontMatrix || FONT_IDENTITY_MATRIX;
983
-
984
- let bold = "normal";
985
- if (fontObj.black) {
986
- bold = "900";
987
- } else if (fontObj.bold) {
988
- bold = "bold";
989
- }
990
- const italic = fontObj.italic ? "italic" : "normal";
991
-
992
- if (size < 0) {
993
- size = -size;
994
- current.fontDirection = -1;
995
- } else {
996
- current.fontDirection = 1;
997
- }
998
- current.fontSize = size;
999
- current.fontFamily = fontObj.loadedName;
1000
- current.fontWeight = bold;
1001
- current.fontStyle = italic;
1002
-
1003
- current.tspan = this.svgFactory.createElement("svg:tspan");
1004
- current.tspan.setAttributeNS(null, "y", pf(-current.y));
1005
- current.xcoords = [];
1006
- current.ycoords = [];
1007
- }
1008
-
1009
- endText() {
1010
- const current = this.current;
1011
- if (
1012
- current.textRenderingMode & TextRenderingMode.ADD_TO_PATH_FLAG &&
1013
- current.txtElement?.hasChildNodes()
1014
- ) {
1015
- // If no glyphs are shown (i.e. no child nodes), no clipping occurs.
1016
- current.element = current.txtElement;
1017
- this.clip("nonzero");
1018
- this.endPath();
1019
- }
1020
- }
1021
-
1022
- // Path properties
1023
- setLineWidth(width) {
1024
- if (width > 0) {
1025
- this.current.lineWidth = width;
1026
- }
1027
- }
1028
-
1029
- setLineCap(style) {
1030
- this.current.lineCap = LINE_CAP_STYLES[style];
1031
- }
1032
-
1033
- setLineJoin(style) {
1034
- this.current.lineJoin = LINE_JOIN_STYLES[style];
1035
- }
1036
-
1037
- setMiterLimit(limit) {
1038
- this.current.miterLimit = limit;
1039
- }
1040
-
1041
- setStrokeAlpha(strokeAlpha) {
1042
- this.current.strokeAlpha = strokeAlpha;
1043
- }
1044
-
1045
- setStrokeRGBColor(r, g, b) {
1046
- this.current.strokeColor = Util.makeHexColor(r, g, b);
1047
- }
1048
-
1049
- setFillAlpha(fillAlpha) {
1050
- this.current.fillAlpha = fillAlpha;
1051
- }
1052
-
1053
- setFillRGBColor(r, g, b) {
1054
- this.current.fillColor = Util.makeHexColor(r, g, b);
1055
- this.current.tspan = this.svgFactory.createElement("svg:tspan");
1056
- this.current.xcoords = [];
1057
- this.current.ycoords = [];
1058
- }
1059
-
1060
- setStrokeColorN(args) {
1061
- this.current.strokeColor = this._makeColorN_Pattern(args);
1062
- }
1063
-
1064
- setFillColorN(args) {
1065
- this.current.fillColor = this._makeColorN_Pattern(args);
1066
- }
1067
-
1068
- shadingFill(args) {
1069
- const width = this.viewport.width;
1070
- const height = this.viewport.height;
1071
- const inv = Util.inverseTransform(this.transformMatrix);
1072
- const bl = Util.applyTransform([0, 0], inv);
1073
- const br = Util.applyTransform([0, height], inv);
1074
- const ul = Util.applyTransform([width, 0], inv);
1075
- const ur = Util.applyTransform([width, height], inv);
1076
- const x0 = Math.min(bl[0], br[0], ul[0], ur[0]);
1077
- const y0 = Math.min(bl[1], br[1], ul[1], ur[1]);
1078
- const x1 = Math.max(bl[0], br[0], ul[0], ur[0]);
1079
- const y1 = Math.max(bl[1], br[1], ul[1], ur[1]);
1080
-
1081
- const rect = this.svgFactory.createElement("svg:rect");
1082
- rect.setAttributeNS(null, "x", x0);
1083
- rect.setAttributeNS(null, "y", y0);
1084
- rect.setAttributeNS(null, "width", x1 - x0);
1085
- rect.setAttributeNS(null, "height", y1 - y0);
1086
- rect.setAttributeNS(null, "fill", this._makeShadingPattern(args));
1087
- if (this.current.fillAlpha < 1) {
1088
- rect.setAttributeNS(null, "fill-opacity", this.current.fillAlpha);
1089
- }
1090
- this._ensureTransformGroup().appendChild(rect);
1091
- }
1092
-
1093
- /**
1094
- * @private
1095
- */
1096
- _makeColorN_Pattern(args) {
1097
- if (args[0] === "TilingPattern") {
1098
- return this._makeTilingPattern(args);
1099
- }
1100
- return this._makeShadingPattern(args);
1101
- }
1102
-
1103
- /**
1104
- * @private
1105
- */
1106
- _makeTilingPattern(args) {
1107
- const color = args[1];
1108
- const operatorList = args[2];
1109
- const matrix = args[3] || IDENTITY_MATRIX;
1110
- const [x0, y0, x1, y1] = args[4];
1111
- const xstep = args[5];
1112
- const ystep = args[6];
1113
- const paintType = args[7];
1114
-
1115
- const tilingId = `shading${shadingCount++}`;
1116
- const [tx0, ty0, tx1, ty1] = Util.normalizeRect([
1117
- ...Util.applyTransform([x0, y0], matrix),
1118
- ...Util.applyTransform([x1, y1], matrix),
1119
- ]);
1120
- const [xscale, yscale] = Util.singularValueDecompose2dScale(matrix);
1121
- const txstep = xstep * xscale;
1122
- const tystep = ystep * yscale;
1123
-
1124
- const tiling = this.svgFactory.createElement("svg:pattern");
1125
- tiling.setAttributeNS(null, "id", tilingId);
1126
- tiling.setAttributeNS(null, "patternUnits", "userSpaceOnUse");
1127
- tiling.setAttributeNS(null, "width", txstep);
1128
- tiling.setAttributeNS(null, "height", tystep);
1129
- tiling.setAttributeNS(null, "x", `${tx0}`);
1130
- tiling.setAttributeNS(null, "y", `${ty0}`);
1131
-
1132
- // Save current state.
1133
- const svg = this.svg;
1134
- const transformMatrix = this.transformMatrix;
1135
- const fillColor = this.current.fillColor;
1136
- const strokeColor = this.current.strokeColor;
1137
-
1138
- const bbox = this.svgFactory.create(tx1 - tx0, ty1 - ty0);
1139
- this.svg = bbox;
1140
- this.transformMatrix = matrix;
1141
- if (paintType === 2) {
1142
- const cssColor = Util.makeHexColor(...color);
1143
- this.current.fillColor = cssColor;
1144
- this.current.strokeColor = cssColor;
1145
- }
1146
- this.executeOpTree(this.convertOpList(operatorList));
1147
-
1148
- // Restore saved state.
1149
- this.svg = svg;
1150
- this.transformMatrix = transformMatrix;
1151
- this.current.fillColor = fillColor;
1152
- this.current.strokeColor = strokeColor;
1153
-
1154
- tiling.appendChild(bbox.childNodes[0]);
1155
- this.defs.appendChild(tiling);
1156
- return `url(#${tilingId})`;
1157
- }
1158
-
1159
- /**
1160
- * @private
1161
- */
1162
- _makeShadingPattern(args) {
1163
- switch (args[0]) {
1164
- case "RadialAxial":
1165
- const shadingId = `shading${shadingCount++}`;
1166
- const colorStops = args[3];
1167
- let gradient;
1168
-
1169
- switch (args[1]) {
1170
- case "axial":
1171
- const point0 = args[4];
1172
- const point1 = args[5];
1173
- gradient = this.svgFactory.createElement("svg:linearGradient");
1174
- gradient.setAttributeNS(null, "id", shadingId);
1175
- gradient.setAttributeNS(null, "gradientUnits", "userSpaceOnUse");
1176
- gradient.setAttributeNS(null, "x1", point0[0]);
1177
- gradient.setAttributeNS(null, "y1", point0[1]);
1178
- gradient.setAttributeNS(null, "x2", point1[0]);
1179
- gradient.setAttributeNS(null, "y2", point1[1]);
1180
- break;
1181
- case "radial":
1182
- const focalPoint = args[4];
1183
- const circlePoint = args[5];
1184
- const focalRadius = args[6];
1185
- const circleRadius = args[7];
1186
- gradient = this.svgFactory.createElement("svg:radialGradient");
1187
- gradient.setAttributeNS(null, "id", shadingId);
1188
- gradient.setAttributeNS(null, "gradientUnits", "userSpaceOnUse");
1189
- gradient.setAttributeNS(null, "cx", circlePoint[0]);
1190
- gradient.setAttributeNS(null, "cy", circlePoint[1]);
1191
- gradient.setAttributeNS(null, "r", circleRadius);
1192
- gradient.setAttributeNS(null, "fx", focalPoint[0]);
1193
- gradient.setAttributeNS(null, "fy", focalPoint[1]);
1194
- gradient.setAttributeNS(null, "fr", focalRadius);
1195
- break;
1196
- default:
1197
- throw new Error(`Unknown RadialAxial type: ${args[1]}`);
1198
- }
1199
- for (const colorStop of colorStops) {
1200
- const stop = this.svgFactory.createElement("svg:stop");
1201
- stop.setAttributeNS(null, "offset", colorStop[0]);
1202
- stop.setAttributeNS(null, "stop-color", colorStop[1]);
1203
- gradient.appendChild(stop);
1204
- }
1205
- this.defs.appendChild(gradient);
1206
- return `url(#${shadingId})`;
1207
- case "Mesh":
1208
- warn("Unimplemented pattern Mesh");
1209
- return null;
1210
- case "Dummy":
1211
- return "hotpink";
1212
- default:
1213
- throw new Error(`Unknown IR type: ${args[0]}`);
1214
- }
1215
- }
1216
-
1217
- setDash(dashArray, dashPhase) {
1218
- this.current.dashArray = dashArray;
1219
- this.current.dashPhase = dashPhase;
1220
- }
1221
-
1222
- constructPath(ops, args) {
1223
- const current = this.current;
1224
- let x = current.x,
1225
- y = current.y;
1226
- let d = [];
1227
- let j = 0;
1228
-
1229
- for (const op of ops) {
1230
- switch (op | 0) {
1231
- case OPS.rectangle:
1232
- x = args[j++];
1233
- y = args[j++];
1234
- const width = args[j++];
1235
- const height = args[j++];
1236
- const xw = x + width;
1237
- const yh = y + height;
1238
- d.push(
1239
- "M",
1240
- pf(x),
1241
- pf(y),
1242
- "L",
1243
- pf(xw),
1244
- pf(y),
1245
- "L",
1246
- pf(xw),
1247
- pf(yh),
1248
- "L",
1249
- pf(x),
1250
- pf(yh),
1251
- "Z"
1252
- );
1253
- break;
1254
- case OPS.moveTo:
1255
- x = args[j++];
1256
- y = args[j++];
1257
- d.push("M", pf(x), pf(y));
1258
- break;
1259
- case OPS.lineTo:
1260
- x = args[j++];
1261
- y = args[j++];
1262
- d.push("L", pf(x), pf(y));
1263
- break;
1264
- case OPS.curveTo:
1265
- x = args[j + 4];
1266
- y = args[j + 5];
1267
- d.push(
1268
- "C",
1269
- pf(args[j]),
1270
- pf(args[j + 1]),
1271
- pf(args[j + 2]),
1272
- pf(args[j + 3]),
1273
- pf(x),
1274
- pf(y)
1275
- );
1276
- j += 6;
1277
- break;
1278
- case OPS.curveTo2:
1279
- d.push(
1280
- "C",
1281
- pf(x),
1282
- pf(y),
1283
- pf(args[j]),
1284
- pf(args[j + 1]),
1285
- pf(args[j + 2]),
1286
- pf(args[j + 3])
1287
- );
1288
- x = args[j + 2];
1289
- y = args[j + 3];
1290
- j += 4;
1291
- break;
1292
- case OPS.curveTo3:
1293
- x = args[j + 2];
1294
- y = args[j + 3];
1295
- d.push(
1296
- "C",
1297
- pf(args[j]),
1298
- pf(args[j + 1]),
1299
- pf(x),
1300
- pf(y),
1301
- pf(x),
1302
- pf(y)
1303
- );
1304
- j += 4;
1305
- break;
1306
- case OPS.closePath:
1307
- d.push("Z");
1308
- break;
1309
- }
1310
- }
1311
-
1312
- d = d.join(" ");
1313
-
1314
- if (
1315
- current.path &&
1316
- ops.length > 0 &&
1317
- ops[0] !== OPS.rectangle &&
1318
- ops[0] !== OPS.moveTo
1319
- ) {
1320
- // If a path does not start with an OPS.rectangle or OPS.moveTo, it has
1321
- // probably been divided into two OPS.constructPath operators by
1322
- // OperatorList. Append the commands to the previous path element.
1323
- d = current.path.getAttributeNS(null, "d") + d;
1324
- } else {
1325
- current.path = this.svgFactory.createElement("svg:path");
1326
- this._ensureTransformGroup().appendChild(current.path);
1327
- }
1328
-
1329
- current.path.setAttributeNS(null, "d", d);
1330
- current.path.setAttributeNS(null, "fill", "none");
1331
-
1332
- // Saving a reference in current.element so that it can be addressed
1333
- // in 'fill' and 'stroke'
1334
- current.element = current.path;
1335
- current.setCurrentPoint(x, y);
1336
- }
1337
-
1338
- endPath() {
1339
- const current = this.current;
1340
-
1341
- // Painting operators end a path.
1342
- current.path = null;
1343
-
1344
- if (!this.pendingClip) {
1345
- return;
1346
- }
1347
- if (!current.element) {
1348
- this.pendingClip = null;
1349
- return;
1350
- }
1351
-
1352
- // Add the current path to a clipping path.
1353
- const clipId = `clippath${clipCount++}`;
1354
- const clipPath = this.svgFactory.createElement("svg:clipPath");
1355
- clipPath.setAttributeNS(null, "id", clipId);
1356
- clipPath.setAttributeNS(null, "transform", pm(this.transformMatrix));
1357
-
1358
- // A deep clone is needed when text is used as a clipping path.
1359
- const clipElement = current.element.cloneNode(true);
1360
- if (this.pendingClip === "evenodd") {
1361
- clipElement.setAttributeNS(null, "clip-rule", "evenodd");
1362
- } else {
1363
- clipElement.setAttributeNS(null, "clip-rule", "nonzero");
1364
- }
1365
- this.pendingClip = null;
1366
- clipPath.appendChild(clipElement);
1367
- this.defs.appendChild(clipPath);
1368
-
1369
- if (current.activeClipUrl) {
1370
- // The previous clipping group content can go out of order -- resetting
1371
- // cached clipGroups.
1372
- current.clipGroup = null;
1373
- for (const prev of this.extraStack) {
1374
- prev.clipGroup = null;
1375
- }
1376
- // Intersect with the previous clipping path.
1377
- clipPath.setAttributeNS(null, "clip-path", current.activeClipUrl);
1378
- }
1379
- current.activeClipUrl = `url(#${clipId})`;
1380
-
1381
- this.tgrp = null;
1382
- }
1383
-
1384
- clip(type) {
1385
- this.pendingClip = type;
1386
- }
1387
-
1388
- closePath() {
1389
- const current = this.current;
1390
- if (current.path) {
1391
- const d = `${current.path.getAttributeNS(null, "d")}Z`;
1392
- current.path.setAttributeNS(null, "d", d);
1393
- }
1394
- }
1395
-
1396
- setLeading(leading) {
1397
- this.current.leading = -leading;
1398
- }
1399
-
1400
- setTextRise(textRise) {
1401
- this.current.textRise = textRise;
1402
- }
1403
-
1404
- setTextRenderingMode(textRenderingMode) {
1405
- this.current.textRenderingMode = textRenderingMode;
1406
- }
1407
-
1408
- setHScale(scale) {
1409
- this.current.textHScale = scale / 100;
1410
- }
1411
-
1412
- setRenderingIntent(intent) {
1413
- // This operation is ignored since we haven't found a use case for it yet.
1414
- }
1415
-
1416
- setFlatness(flatness) {
1417
- // This operation is ignored since we haven't found a use case for it yet.
1418
- }
1419
-
1420
- setGState(states) {
1421
- for (const [key, value] of states) {
1422
- switch (key) {
1423
- case "LW":
1424
- this.setLineWidth(value);
1425
- break;
1426
- case "LC":
1427
- this.setLineCap(value);
1428
- break;
1429
- case "LJ":
1430
- this.setLineJoin(value);
1431
- break;
1432
- case "ML":
1433
- this.setMiterLimit(value);
1434
- break;
1435
- case "D":
1436
- this.setDash(value[0], value[1]);
1437
- break;
1438
- case "RI":
1439
- this.setRenderingIntent(value);
1440
- break;
1441
- case "FL":
1442
- this.setFlatness(value);
1443
- break;
1444
- case "Font":
1445
- this.setFont(value);
1446
- break;
1447
- case "CA":
1448
- this.setStrokeAlpha(value);
1449
- break;
1450
- case "ca":
1451
- this.setFillAlpha(value);
1452
- break;
1453
- default:
1454
- warn(`Unimplemented graphic state operator ${key}`);
1455
- break;
1456
- }
1457
- }
1458
- }
1459
-
1460
- fill() {
1461
- const current = this.current;
1462
- if (current.element) {
1463
- current.element.setAttributeNS(null, "fill", current.fillColor);
1464
- current.element.setAttributeNS(null, "fill-opacity", current.fillAlpha);
1465
- this.endPath();
1466
- }
1467
- }
1468
-
1469
- stroke() {
1470
- const current = this.current;
1471
- if (current.element) {
1472
- this._setStrokeAttributes(current.element);
1473
- current.element.setAttributeNS(null, "fill", "none");
1474
- this.endPath();
1475
- }
1476
- }
1477
-
1478
- /**
1479
- * @private
1480
- */
1481
- _setStrokeAttributes(element, lineWidthScale = 1) {
1482
- const current = this.current;
1483
- let dashArray = current.dashArray;
1484
- if (lineWidthScale !== 1 && dashArray.length > 0) {
1485
- dashArray = dashArray.map(function (value) {
1486
- return lineWidthScale * value;
1487
- });
1488
- }
1489
- element.setAttributeNS(null, "stroke", current.strokeColor);
1490
- element.setAttributeNS(null, "stroke-opacity", current.strokeAlpha);
1491
- element.setAttributeNS(null, "stroke-miterlimit", pf(current.miterLimit));
1492
- element.setAttributeNS(null, "stroke-linecap", current.lineCap);
1493
- element.setAttributeNS(null, "stroke-linejoin", current.lineJoin);
1494
- element.setAttributeNS(
1495
- null,
1496
- "stroke-width",
1497
- pf(lineWidthScale * current.lineWidth) + "px"
1498
- );
1499
- element.setAttributeNS(
1500
- null,
1501
- "stroke-dasharray",
1502
- dashArray.map(pf).join(" ")
1503
- );
1504
- element.setAttributeNS(
1505
- null,
1506
- "stroke-dashoffset",
1507
- pf(lineWidthScale * current.dashPhase) + "px"
1508
- );
1509
- }
1510
-
1511
- eoFill() {
1512
- if (this.current.element) {
1513
- this.current.element.setAttributeNS(null, "fill-rule", "evenodd");
1514
- }
1515
- this.fill();
1516
- }
1517
-
1518
- fillStroke() {
1519
- // Order is important since stroke wants fill to be none.
1520
- // First stroke, then if fill needed, it will be overwritten.
1521
- this.stroke();
1522
- this.fill();
1523
- }
1524
-
1525
- eoFillStroke() {
1526
- if (this.current.element) {
1527
- this.current.element.setAttributeNS(null, "fill-rule", "evenodd");
1528
- }
1529
- this.fillStroke();
1530
- }
1531
-
1532
- closeStroke() {
1533
- this.closePath();
1534
- this.stroke();
1535
- }
1536
-
1537
- closeFillStroke() {
1538
- this.closePath();
1539
- this.fillStroke();
1540
- }
1541
-
1542
- closeEOFillStroke() {
1543
- this.closePath();
1544
- this.eoFillStroke();
1545
- }
1546
-
1547
- paintSolidColorImageMask() {
1548
- const rect = this.svgFactory.createElement("svg:rect");
1549
- rect.setAttributeNS(null, "x", "0");
1550
- rect.setAttributeNS(null, "y", "0");
1551
- rect.setAttributeNS(null, "width", "1px");
1552
- rect.setAttributeNS(null, "height", "1px");
1553
- rect.setAttributeNS(null, "fill", this.current.fillColor);
1554
-
1555
- this._ensureTransformGroup().appendChild(rect);
1556
- }
1557
-
1558
- paintImageXObject(objId) {
1559
- const imgData = objId.startsWith("g_")
1560
- ? this.commonObjs.get(objId)
1561
- : this.objs.get(objId);
1562
- if (!imgData) {
1563
- warn(`Dependent image with object ID ${objId} is not ready yet`);
1564
- return;
1565
- }
1566
- this.paintInlineImageXObject(imgData);
1567
- }
1568
-
1569
- paintInlineImageXObject(imgData, mask) {
1570
- const width = imgData.width;
1571
- const height = imgData.height;
1572
-
1573
- const imgSrc = convertImgDataToPng(imgData, this.forceDataSchema, !!mask);
1574
- const cliprect = this.svgFactory.createElement("svg:rect");
1575
- cliprect.setAttributeNS(null, "x", "0");
1576
- cliprect.setAttributeNS(null, "y", "0");
1577
- cliprect.setAttributeNS(null, "width", pf(width));
1578
- cliprect.setAttributeNS(null, "height", pf(height));
1579
- this.current.element = cliprect;
1580
- this.clip("nonzero");
1581
-
1582
- const imgEl = this.svgFactory.createElement("svg:image");
1583
- imgEl.setAttributeNS(XLINK_NS, "xlink:href", imgSrc);
1584
- imgEl.setAttributeNS(null, "x", "0");
1585
- imgEl.setAttributeNS(null, "y", pf(-height));
1586
- imgEl.setAttributeNS(null, "width", pf(width) + "px");
1587
- imgEl.setAttributeNS(null, "height", pf(height) + "px");
1588
- imgEl.setAttributeNS(
1589
- null,
1590
- "transform",
1591
- `scale(${pf(1 / width)} ${pf(-1 / height)})`
1592
- );
1593
- if (mask) {
1594
- mask.appendChild(imgEl);
1595
- } else {
1596
- this._ensureTransformGroup().appendChild(imgEl);
1597
- }
1598
- }
1599
-
1600
- paintImageMaskXObject(imgData) {
1601
- const current = this.current;
1602
- const width = imgData.width;
1603
- const height = imgData.height;
1604
- const fillColor = current.fillColor;
1605
-
1606
- current.maskId = `mask${maskCount++}`;
1607
- const mask = this.svgFactory.createElement("svg:mask");
1608
- mask.setAttributeNS(null, "id", current.maskId);
1609
-
1610
- const rect = this.svgFactory.createElement("svg:rect");
1611
- rect.setAttributeNS(null, "x", "0");
1612
- rect.setAttributeNS(null, "y", "0");
1613
- rect.setAttributeNS(null, "width", pf(width));
1614
- rect.setAttributeNS(null, "height", pf(height));
1615
- rect.setAttributeNS(null, "fill", fillColor);
1616
- rect.setAttributeNS(null, "mask", `url(#${current.maskId})`);
1617
-
1618
- this.defs.appendChild(mask);
1619
- this._ensureTransformGroup().appendChild(rect);
1620
-
1621
- this.paintInlineImageXObject(imgData, mask);
1622
- }
1623
-
1624
- paintFormXObjectBegin(matrix, bbox) {
1625
- if (Array.isArray(matrix) && matrix.length === 6) {
1626
- this.transform(
1627
- matrix[0],
1628
- matrix[1],
1629
- matrix[2],
1630
- matrix[3],
1631
- matrix[4],
1632
- matrix[5]
1633
- );
1634
- }
1635
-
1636
- if (bbox) {
1637
- const width = bbox[2] - bbox[0];
1638
- const height = bbox[3] - bbox[1];
1639
-
1640
- const cliprect = this.svgFactory.createElement("svg:rect");
1641
- cliprect.setAttributeNS(null, "x", bbox[0]);
1642
- cliprect.setAttributeNS(null, "y", bbox[1]);
1643
- cliprect.setAttributeNS(null, "width", pf(width));
1644
- cliprect.setAttributeNS(null, "height", pf(height));
1645
- this.current.element = cliprect;
1646
- this.clip("nonzero");
1647
- this.endPath();
1648
- }
1649
- }
1650
-
1651
- paintFormXObjectEnd() {}
1652
-
1653
- /**
1654
- * @private
1655
- */
1656
- _initialize(viewport) {
1657
- const svg = this.svgFactory.create(viewport.width, viewport.height);
1658
-
1659
- // Create the definitions element.
1660
- const definitions = this.svgFactory.createElement("svg:defs");
1661
- svg.appendChild(definitions);
1662
- this.defs = definitions;
1663
-
1664
- // Create the root group element, which acts a container for all other
1665
- // groups and applies the viewport transform.
1666
- const rootGroup = this.svgFactory.createElement("svg:g");
1667
- rootGroup.setAttributeNS(null, "transform", pm(viewport.transform));
1668
- svg.appendChild(rootGroup);
1669
-
1670
- // For the construction of the SVG image we are only interested in the
1671
- // root group, so we expose it as the entry point of the SVG image for
1672
- // the other code in this class.
1673
- this.svg = rootGroup;
1674
-
1675
- return svg;
1676
- }
1677
-
1678
- /**
1679
- * @private
1680
- */
1681
- _ensureClipGroup() {
1682
- if (!this.current.clipGroup) {
1683
- const clipGroup = this.svgFactory.createElement("svg:g");
1684
- clipGroup.setAttributeNS(null, "clip-path", this.current.activeClipUrl);
1685
- this.svg.appendChild(clipGroup);
1686
- this.current.clipGroup = clipGroup;
1687
- }
1688
- return this.current.clipGroup;
1689
- }
1690
-
1691
- /**
1692
- * @private
1693
- */
1694
- _ensureTransformGroup() {
1695
- if (!this.tgrp) {
1696
- this.tgrp = this.svgFactory.createElement("svg:g");
1697
- this.tgrp.setAttributeNS(null, "transform", pm(this.transformMatrix));
1698
- if (this.current.activeClipUrl) {
1699
- this._ensureClipGroup().appendChild(this.tgrp);
1700
- } else {
1701
- this.svg.appendChild(this.tgrp);
1702
- }
1703
- }
1704
- return this.tgrp;
1705
- }
1706
- };
1707
- }
1708
-
1709
- export { SVGGraphics };