pdfmake 0.3.0-beta.8 → 0.3.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 (87) hide show
  1. package/CHANGELOG.md +7 -40
  2. package/LICENSE +1 -1
  3. package/README.md +78 -85
  4. package/build/pdfmake.js +60308 -68400
  5. package/build/pdfmake.js.map +1 -1
  6. package/build/pdfmake.min.js +2 -2
  7. package/build/pdfmake.min.js.map +1 -1
  8. package/build/vfs_fonts.js +4 -4
  9. package/fonts/Roboto/Roboto-Italic.ttf +0 -0
  10. package/fonts/Roboto/Roboto-Medium.ttf +0 -0
  11. package/fonts/Roboto/Roboto-MediumItalic.ttf +0 -0
  12. package/fonts/Roboto/Roboto-Regular.ttf +0 -0
  13. package/js/3rd-party/svg-to-pdfkit/source.js +3626 -0
  14. package/js/3rd-party/svg-to-pdfkit.js +7 -0
  15. package/js/DocMeasure.js +645 -0
  16. package/js/DocPreprocessor.js +253 -0
  17. package/js/DocumentContext.js +305 -0
  18. package/js/ElementWriter.js +354 -0
  19. package/js/LayoutBuilder.js +1105 -0
  20. package/js/Line.js +105 -0
  21. package/js/OutputDocument.js +64 -0
  22. package/js/OutputDocumentServer.js +22 -0
  23. package/js/PDFDocument.js +144 -0
  24. package/js/PageElementWriter.js +155 -0
  25. package/js/PageSize.js +74 -0
  26. package/js/Printer.js +291 -0
  27. package/js/Renderer.js +383 -0
  28. package/js/SVGMeasure.js +69 -0
  29. package/js/StyleContextStack.js +168 -0
  30. package/js/TableProcessor.js +548 -0
  31. package/js/TextBreaker.js +166 -0
  32. package/js/TextDecorator.js +143 -0
  33. package/js/TextInlines.js +206 -0
  34. package/js/URLResolver.js +43 -0
  35. package/js/base.js +52 -0
  36. package/js/browser-extensions/OutputDocumentBrowser.js +81 -0
  37. package/js/browser-extensions/fonts/Roboto.js +38 -0
  38. package/js/browser-extensions/index.js +53 -0
  39. package/js/browser-extensions/pdfMake.js +3 -0
  40. package/js/browser-extensions/standard-fonts/Courier.js +38 -0
  41. package/js/browser-extensions/standard-fonts/Helvetica.js +38 -0
  42. package/js/browser-extensions/standard-fonts/Symbol.js +23 -0
  43. package/js/browser-extensions/standard-fonts/Times.js +38 -0
  44. package/js/browser-extensions/standard-fonts/ZapfDingbats.js +23 -0
  45. package/js/browser-extensions/virtual-fs-cjs.js +3 -0
  46. package/js/columnCalculator.js +148 -0
  47. package/js/helpers/node.js +98 -0
  48. package/js/helpers/tools.js +46 -0
  49. package/js/helpers/variableType.js +59 -0
  50. package/js/index.js +15 -0
  51. package/js/qrEnc.js +721 -0
  52. package/js/standardPageSizes.js +56 -0
  53. package/js/tableLayouts.js +98 -0
  54. package/js/virtual-fs.js +60 -0
  55. package/package.json +25 -24
  56. package/src/DocMeasure.js +28 -7
  57. package/src/DocPreprocessor.js +25 -6
  58. package/src/DocumentContext.js +62 -33
  59. package/src/ElementWriter.js +30 -7
  60. package/src/LayoutBuilder.js +557 -120
  61. package/src/OutputDocument.js +23 -37
  62. package/src/OutputDocumentServer.js +6 -11
  63. package/src/PDFDocument.js +1 -1
  64. package/src/PageElementWriter.js +21 -2
  65. package/src/Printer.js +134 -131
  66. package/src/Renderer.js +13 -15
  67. package/src/SVGMeasure.js +2 -2
  68. package/src/StyleContextStack.js +7 -44
  69. package/src/TableProcessor.js +62 -22
  70. package/src/TextBreaker.js +24 -5
  71. package/src/TextInlines.js +1 -1
  72. package/src/URLResolver.js +24 -58
  73. package/src/base.js +1 -1
  74. package/src/browser-extensions/OutputDocumentBrowser.js +33 -71
  75. package/src/browser-extensions/index.js +3 -3
  76. package/src/browser-extensions/pdfMake.js +0 -14
  77. package/src/browser-extensions/standard-fonts/Courier.js +4 -4
  78. package/src/browser-extensions/standard-fonts/Helvetica.js +4 -4
  79. package/src/browser-extensions/standard-fonts/Symbol.js +1 -1
  80. package/src/browser-extensions/standard-fonts/Times.js +4 -4
  81. package/src/browser-extensions/standard-fonts/ZapfDingbats.js +1 -1
  82. package/src/columnCalculator.js +24 -3
  83. package/src/helpers/tools.js +5 -0
  84. package/src/helpers/variableType.js +11 -0
  85. package/src/index.js +1 -1
  86. package/standard-fonts/Helvetica.js +0 -1
  87. package/src/browser-extensions/URLBrowserResolver.js +0 -84
@@ -0,0 +1,3626 @@
1
+ "use strict";
2
+
3
+ var SVGtoPDF = function (doc, svg, x, y, options) {
4
+ "use strict";
5
+
6
+ const NamedColors = {
7
+ aliceblue: [240, 248, 255],
8
+ antiquewhite: [250, 235, 215],
9
+ aqua: [0, 255, 255],
10
+ aquamarine: [127, 255, 212],
11
+ azure: [240, 255, 255],
12
+ beige: [245, 245, 220],
13
+ bisque: [255, 228, 196],
14
+ black: [0, 0, 0],
15
+ blanchedalmond: [255, 235, 205],
16
+ blue: [0, 0, 255],
17
+ blueviolet: [138, 43, 226],
18
+ brown: [165, 42, 42],
19
+ burlywood: [222, 184, 135],
20
+ cadetblue: [95, 158, 160],
21
+ chartreuse: [127, 255, 0],
22
+ chocolate: [210, 105, 30],
23
+ coral: [255, 127, 80],
24
+ cornflowerblue: [100, 149, 237],
25
+ cornsilk: [255, 248, 220],
26
+ crimson: [220, 20, 60],
27
+ cyan: [0, 255, 255],
28
+ darkblue: [0, 0, 139],
29
+ darkcyan: [0, 139, 139],
30
+ darkgoldenrod: [184, 134, 11],
31
+ darkgray: [169, 169, 169],
32
+ darkgrey: [169, 169, 169],
33
+ darkgreen: [0, 100, 0],
34
+ darkkhaki: [189, 183, 107],
35
+ darkmagenta: [139, 0, 139],
36
+ darkolivegreen: [85, 107, 47],
37
+ darkorange: [255, 140, 0],
38
+ darkorchid: [153, 50, 204],
39
+ darkred: [139, 0, 0],
40
+ darksalmon: [233, 150, 122],
41
+ darkseagreen: [143, 188, 143],
42
+ darkslateblue: [72, 61, 139],
43
+ darkslategray: [47, 79, 79],
44
+ darkslategrey: [47, 79, 79],
45
+ darkturquoise: [0, 206, 209],
46
+ darkviolet: [148, 0, 211],
47
+ deeppink: [255, 20, 147],
48
+ deepskyblue: [0, 191, 255],
49
+ dimgray: [105, 105, 105],
50
+ dimgrey: [105, 105, 105],
51
+ dodgerblue: [30, 144, 255],
52
+ firebrick: [178, 34, 34],
53
+ floralwhite: [255, 250, 240],
54
+ forestgreen: [34, 139, 34],
55
+ fuchsia: [255, 0, 255],
56
+ gainsboro: [220, 220, 220],
57
+ ghostwhite: [248, 248, 255],
58
+ gold: [255, 215, 0],
59
+ goldenrod: [218, 165, 32],
60
+ gray: [128, 128, 128],
61
+ grey: [128, 128, 128],
62
+ green: [0, 128, 0],
63
+ greenyellow: [173, 255, 47],
64
+ honeydew: [240, 255, 240],
65
+ hotpink: [255, 105, 180],
66
+ indianred: [205, 92, 92],
67
+ indigo: [75, 0, 130],
68
+ ivory: [255, 255, 240],
69
+ khaki: [240, 230, 140],
70
+ lavender: [230, 230, 250],
71
+ lavenderblush: [255, 240, 245],
72
+ lawngreen: [124, 252, 0],
73
+ lemonchiffon: [255, 250, 205],
74
+ lightblue: [173, 216, 230],
75
+ lightcoral: [240, 128, 128],
76
+ lightcyan: [224, 255, 255],
77
+ lightgoldenrodyellow: [250, 250, 210],
78
+ lightgray: [211, 211, 211],
79
+ lightgrey: [211, 211, 211],
80
+ lightgreen: [144, 238, 144],
81
+ lightpink: [255, 182, 193],
82
+ lightsalmon: [255, 160, 122],
83
+ lightseagreen: [32, 178, 170],
84
+ lightskyblue: [135, 206, 250],
85
+ lightslategray: [119, 136, 153],
86
+ lightslategrey: [119, 136, 153],
87
+ lightsteelblue: [176, 196, 222],
88
+ lightyellow: [255, 255, 224],
89
+ lime: [0, 255, 0],
90
+ limegreen: [50, 205, 50],
91
+ linen: [250, 240, 230],
92
+ magenta: [255, 0, 255],
93
+ maroon: [128, 0, 0],
94
+ mediumaquamarine: [102, 205, 170],
95
+ mediumblue: [0, 0, 205],
96
+ mediumorchid: [186, 85, 211],
97
+ mediumpurple: [147, 112, 219],
98
+ mediumseagreen: [60, 179, 113],
99
+ mediumslateblue: [123, 104, 238],
100
+ mediumspringgreen: [0, 250, 154],
101
+ mediumturquoise: [72, 209, 204],
102
+ mediumvioletred: [199, 21, 133],
103
+ midnightblue: [25, 25, 112],
104
+ mintcream: [245, 255, 250],
105
+ mistyrose: [255, 228, 225],
106
+ moccasin: [255, 228, 181],
107
+ navajowhite: [255, 222, 173],
108
+ navy: [0, 0, 128],
109
+ oldlace: [253, 245, 230],
110
+ olive: [128, 128, 0],
111
+ olivedrab: [107, 142, 35],
112
+ orange: [255, 165, 0],
113
+ orangered: [255, 69, 0],
114
+ orchid: [218, 112, 214],
115
+ palegoldenrod: [238, 232, 170],
116
+ palegreen: [152, 251, 152],
117
+ paleturquoise: [175, 238, 238],
118
+ palevioletred: [219, 112, 147],
119
+ papayawhip: [255, 239, 213],
120
+ peachpuff: [255, 218, 185],
121
+ peru: [205, 133, 63],
122
+ pink: [255, 192, 203],
123
+ plum: [221, 160, 221],
124
+ powderblue: [176, 224, 230],
125
+ purple: [128, 0, 128],
126
+ rebeccapurple: [102, 51, 153],
127
+ red: [255, 0, 0],
128
+ rosybrown: [188, 143, 143],
129
+ royalblue: [65, 105, 225],
130
+ saddlebrown: [139, 69, 19],
131
+ salmon: [250, 128, 114],
132
+ sandybrown: [244, 164, 96],
133
+ seagreen: [46, 139, 87],
134
+ seashell: [255, 245, 238],
135
+ sienna: [160, 82, 45],
136
+ silver: [192, 192, 192],
137
+ skyblue: [135, 206, 235],
138
+ slateblue: [106, 90, 205],
139
+ slategray: [112, 128, 144],
140
+ slategrey: [112, 128, 144],
141
+ snow: [255, 250, 250],
142
+ springgreen: [0, 255, 127],
143
+ steelblue: [70, 130, 180],
144
+ tan: [210, 180, 140],
145
+ teal: [0, 128, 128],
146
+ thistle: [216, 191, 216],
147
+ tomato: [255, 99, 71],
148
+ turquoise: [64, 224, 208],
149
+ violet: [238, 130, 238],
150
+ wheat: [245, 222, 179],
151
+ white: [255, 255, 255],
152
+ whitesmoke: [245, 245, 245],
153
+ yellow: [255, 255, 0]
154
+ };
155
+ const DefaultColors = {
156
+ black: [NamedColors.black, 1],
157
+ white: [NamedColors.white, 1],
158
+ transparent: [NamedColors.black, 0]
159
+ };
160
+ const Entities = {
161
+ quot: 34,
162
+ amp: 38,
163
+ lt: 60,
164
+ gt: 62,
165
+ apos: 39,
166
+ OElig: 338,
167
+ oelig: 339,
168
+ Scaron: 352,
169
+ scaron: 353,
170
+ Yuml: 376,
171
+ circ: 710,
172
+ tilde: 732,
173
+ ensp: 8194,
174
+ emsp: 8195,
175
+ thinsp: 8201,
176
+ zwnj: 8204,
177
+ zwj: 8205,
178
+ lrm: 8206,
179
+ rlm: 8207,
180
+ ndash: 8211,
181
+ mdash: 8212,
182
+ lsquo: 8216,
183
+ rsquo: 8217,
184
+ sbquo: 8218,
185
+ ldquo: 8220,
186
+ rdquo: 8221,
187
+ bdquo: 8222,
188
+ dagger: 8224,
189
+ Dagger: 8225,
190
+ permil: 8240,
191
+ lsaquo: 8249,
192
+ rsaquo: 8250,
193
+ euro: 8364,
194
+ nbsp: 160,
195
+ iexcl: 161,
196
+ cent: 162,
197
+ pound: 163,
198
+ curren: 164,
199
+ yen: 165,
200
+ brvbar: 166,
201
+ sect: 167,
202
+ uml: 168,
203
+ copy: 169,
204
+ ordf: 170,
205
+ laquo: 171,
206
+ not: 172,
207
+ shy: 173,
208
+ reg: 174,
209
+ macr: 175,
210
+ deg: 176,
211
+ plusmn: 177,
212
+ sup2: 178,
213
+ sup3: 179,
214
+ acute: 180,
215
+ micro: 181,
216
+ para: 182,
217
+ middot: 183,
218
+ cedil: 184,
219
+ sup1: 185,
220
+ ordm: 186,
221
+ raquo: 187,
222
+ frac14: 188,
223
+ frac12: 189,
224
+ frac34: 190,
225
+ iquest: 191,
226
+ Agrave: 192,
227
+ Aacute: 193,
228
+ Acirc: 194,
229
+ Atilde: 195,
230
+ Auml: 196,
231
+ Aring: 197,
232
+ AElig: 198,
233
+ Ccedil: 199,
234
+ Egrave: 200,
235
+ Eacute: 201,
236
+ Ecirc: 202,
237
+ Euml: 203,
238
+ Igrave: 204,
239
+ Iacute: 205,
240
+ Icirc: 206,
241
+ Iuml: 207,
242
+ ETH: 208,
243
+ Ntilde: 209,
244
+ Ograve: 210,
245
+ Oacute: 211,
246
+ Ocirc: 212,
247
+ Otilde: 213,
248
+ Ouml: 214,
249
+ times: 215,
250
+ Oslash: 216,
251
+ Ugrave: 217,
252
+ Uacute: 218,
253
+ Ucirc: 219,
254
+ Uuml: 220,
255
+ Yacute: 221,
256
+ THORN: 222,
257
+ szlig: 223,
258
+ agrave: 224,
259
+ aacute: 225,
260
+ acirc: 226,
261
+ atilde: 227,
262
+ auml: 228,
263
+ aring: 229,
264
+ aelig: 230,
265
+ ccedil: 231,
266
+ egrave: 232,
267
+ eacute: 233,
268
+ ecirc: 234,
269
+ euml: 235,
270
+ igrave: 236,
271
+ iacute: 237,
272
+ icirc: 238,
273
+ iuml: 239,
274
+ eth: 240,
275
+ ntilde: 241,
276
+ ograve: 242,
277
+ oacute: 243,
278
+ ocirc: 244,
279
+ otilde: 245,
280
+ ouml: 246,
281
+ divide: 247,
282
+ oslash: 248,
283
+ ugrave: 249,
284
+ uacute: 250,
285
+ ucirc: 251,
286
+ uuml: 252,
287
+ yacute: 253,
288
+ thorn: 254,
289
+ yuml: 255,
290
+ fnof: 402,
291
+ Alpha: 913,
292
+ Beta: 914,
293
+ Gamma: 915,
294
+ Delta: 916,
295
+ Epsilon: 917,
296
+ Zeta: 918,
297
+ Eta: 919,
298
+ Theta: 920,
299
+ Iota: 921,
300
+ Kappa: 922,
301
+ Lambda: 923,
302
+ Mu: 924,
303
+ Nu: 925,
304
+ Xi: 926,
305
+ Omicron: 927,
306
+ Pi: 928,
307
+ Rho: 929,
308
+ Sigma: 931,
309
+ Tau: 932,
310
+ Upsilon: 933,
311
+ Phi: 934,
312
+ Chi: 935,
313
+ Psi: 936,
314
+ Omega: 937,
315
+ alpha: 945,
316
+ beta: 946,
317
+ gamma: 947,
318
+ delta: 948,
319
+ epsilon: 949,
320
+ zeta: 950,
321
+ eta: 951,
322
+ theta: 952,
323
+ iota: 953,
324
+ kappa: 954,
325
+ lambda: 955,
326
+ mu: 956,
327
+ nu: 957,
328
+ xi: 958,
329
+ omicron: 959,
330
+ pi: 960,
331
+ rho: 961,
332
+ sigmaf: 962,
333
+ sigma: 963,
334
+ tau: 964,
335
+ upsilon: 965,
336
+ phi: 966,
337
+ chi: 967,
338
+ psi: 968,
339
+ omega: 969,
340
+ thetasym: 977,
341
+ upsih: 978,
342
+ piv: 982,
343
+ bull: 8226,
344
+ hellip: 8230,
345
+ prime: 8242,
346
+ Prime: 8243,
347
+ oline: 8254,
348
+ frasl: 8260,
349
+ weierp: 8472,
350
+ image: 8465,
351
+ real: 8476,
352
+ trade: 8482,
353
+ alefsym: 8501,
354
+ larr: 8592,
355
+ uarr: 8593,
356
+ rarr: 8594,
357
+ darr: 8595,
358
+ harr: 8596,
359
+ crarr: 8629,
360
+ lArr: 8656,
361
+ uArr: 8657,
362
+ rArr: 8658,
363
+ dArr: 8659,
364
+ hArr: 8660,
365
+ forall: 8704,
366
+ part: 8706,
367
+ exist: 8707,
368
+ empty: 8709,
369
+ nabla: 8711,
370
+ isin: 8712,
371
+ notin: 8713,
372
+ ni: 8715,
373
+ prod: 8719,
374
+ sum: 8721,
375
+ minus: 8722,
376
+ lowast: 8727,
377
+ radic: 8730,
378
+ prop: 8733,
379
+ infin: 8734,
380
+ ang: 8736,
381
+ and: 8743,
382
+ or: 8744,
383
+ cap: 8745,
384
+ cup: 8746,
385
+ int: 8747,
386
+ there4: 8756,
387
+ sim: 8764,
388
+ cong: 8773,
389
+ asymp: 8776,
390
+ ne: 8800,
391
+ equiv: 8801,
392
+ le: 8804,
393
+ ge: 8805,
394
+ sub: 8834,
395
+ sup: 8835,
396
+ nsub: 8836,
397
+ sube: 8838,
398
+ supe: 8839,
399
+ oplus: 8853,
400
+ otimes: 8855,
401
+ perp: 8869,
402
+ sdot: 8901,
403
+ lceil: 8968,
404
+ rceil: 8969,
405
+ lfloor: 8970,
406
+ rfloor: 8971,
407
+ lang: 9001,
408
+ rang: 9002,
409
+ loz: 9674,
410
+ spades: 9824,
411
+ clubs: 9827,
412
+ hearts: 9829,
413
+ diams: 9830
414
+ };
415
+ const PathArguments = {
416
+ A: 7,
417
+ a: 7,
418
+ C: 6,
419
+ c: 6,
420
+ H: 1,
421
+ h: 1,
422
+ L: 2,
423
+ l: 2,
424
+ M: 2,
425
+ m: 2,
426
+ Q: 4,
427
+ q: 4,
428
+ S: 4,
429
+ s: 4,
430
+ T: 2,
431
+ t: 2,
432
+ V: 1,
433
+ v: 1,
434
+ Z: 0,
435
+ z: 0
436
+ };
437
+ const PathFlags = {
438
+ A3: true,
439
+ A4: true,
440
+ a3: true,
441
+ a4: true
442
+ };
443
+ const Properties = {
444
+ 'color': {
445
+ inherit: true,
446
+ initial: undefined
447
+ },
448
+ 'visibility': {
449
+ inherit: true,
450
+ initial: 'visible',
451
+ values: {
452
+ 'hidden': 'hidden',
453
+ 'collapse': 'hidden',
454
+ 'visible': 'visible'
455
+ }
456
+ },
457
+ 'fill': {
458
+ inherit: true,
459
+ initial: DefaultColors.black
460
+ },
461
+ 'stroke': {
462
+ inherit: true,
463
+ initial: 'none'
464
+ },
465
+ 'stop-color': {
466
+ inherit: false,
467
+ initial: DefaultColors.black
468
+ },
469
+ 'fill-opacity': {
470
+ inherit: true,
471
+ initial: 1
472
+ },
473
+ 'stroke-opacity': {
474
+ inherit: true,
475
+ initial: 1
476
+ },
477
+ 'stop-opacity': {
478
+ inherit: false,
479
+ initial: 1
480
+ },
481
+ 'fill-rule': {
482
+ inherit: true,
483
+ initial: 'nonzero',
484
+ values: {
485
+ 'nonzero': 'nonzero',
486
+ 'evenodd': 'evenodd'
487
+ }
488
+ },
489
+ 'clip-rule': {
490
+ inherit: true,
491
+ initial: 'nonzero',
492
+ values: {
493
+ 'nonzero': 'nonzero',
494
+ 'evenodd': 'evenodd'
495
+ }
496
+ },
497
+ 'stroke-width': {
498
+ inherit: true,
499
+ initial: 1
500
+ },
501
+ 'stroke-dasharray': {
502
+ inherit: true,
503
+ initial: []
504
+ },
505
+ 'stroke-dashoffset': {
506
+ inherit: true,
507
+ initial: 0
508
+ },
509
+ 'stroke-miterlimit': {
510
+ inherit: true,
511
+ initial: 4
512
+ },
513
+ 'stroke-linejoin': {
514
+ inherit: true,
515
+ initial: 'miter',
516
+ values: {
517
+ 'miter': 'miter',
518
+ 'round': 'round',
519
+ 'bevel': 'bevel'
520
+ }
521
+ },
522
+ 'stroke-linecap': {
523
+ inherit: true,
524
+ initial: 'butt',
525
+ values: {
526
+ 'butt': 'butt',
527
+ 'round': 'round',
528
+ 'square': 'square'
529
+ }
530
+ },
531
+ 'font-size': {
532
+ inherit: true,
533
+ initial: 16,
534
+ values: {
535
+ 'xx-small': 9,
536
+ 'x-small': 10,
537
+ 'small': 13,
538
+ 'medium': 16,
539
+ 'large': 18,
540
+ 'x-large': 24,
541
+ 'xx-large': 32
542
+ }
543
+ },
544
+ 'font-family': {
545
+ inherit: true,
546
+ initial: 'sans-serif'
547
+ },
548
+ 'font-weight': {
549
+ inherit: true,
550
+ initial: 'normal',
551
+ values: {
552
+ '600': 'bold',
553
+ '700': 'bold',
554
+ '800': 'bold',
555
+ '900': 'bold',
556
+ 'bold': 'bold',
557
+ 'bolder': 'bold',
558
+ '500': 'normal',
559
+ '400': 'normal',
560
+ '300': 'normal',
561
+ '200': 'normal',
562
+ '100': 'normal',
563
+ 'normal': 'normal',
564
+ 'lighter': 'normal'
565
+ }
566
+ },
567
+ 'font-style': {
568
+ inherit: true,
569
+ initial: 'normal',
570
+ values: {
571
+ 'italic': 'italic',
572
+ 'oblique': 'italic',
573
+ 'normal': 'normal'
574
+ }
575
+ },
576
+ 'text-anchor': {
577
+ inherit: true,
578
+ initial: 'start',
579
+ values: {
580
+ 'start': 'start',
581
+ 'middle': 'middle',
582
+ 'end': 'end'
583
+ }
584
+ },
585
+ 'direction': {
586
+ inherit: true,
587
+ initial: 'ltr',
588
+ values: {
589
+ 'ltr': 'ltr',
590
+ 'rtl': 'rtl'
591
+ }
592
+ },
593
+ 'dominant-baseline': {
594
+ inherit: true,
595
+ initial: 'baseline',
596
+ values: {
597
+ 'auto': 'baseline',
598
+ 'baseline': 'baseline',
599
+ 'before-edge': 'before-edge',
600
+ 'text-before-edge': 'before-edge',
601
+ 'middle': 'middle',
602
+ 'central': 'central',
603
+ 'after-edge': 'after-edge',
604
+ 'text-after-edge': 'after-edge',
605
+ 'ideographic': 'ideographic',
606
+ 'alphabetic': 'alphabetic',
607
+ 'hanging': 'hanging',
608
+ 'mathematical': 'mathematical'
609
+ }
610
+ },
611
+ 'alignment-baseline': {
612
+ inherit: false,
613
+ initial: undefined,
614
+ values: {
615
+ 'auto': 'baseline',
616
+ 'baseline': 'baseline',
617
+ 'before-edge': 'before-edge',
618
+ 'text-before-edge': 'before-edge',
619
+ 'middle': 'middle',
620
+ 'central': 'central',
621
+ 'after-edge': 'after-edge',
622
+ 'text-after-edge': 'after-edge',
623
+ 'ideographic': 'ideographic',
624
+ 'alphabetic': 'alphabetic',
625
+ 'hanging': 'hanging',
626
+ 'mathematical': 'mathematical'
627
+ }
628
+ },
629
+ 'baseline-shift': {
630
+ inherit: true,
631
+ initial: 'baseline',
632
+ values: {
633
+ 'baseline': 'baseline',
634
+ 'sub': 'sub',
635
+ 'super': 'super'
636
+ }
637
+ },
638
+ 'word-spacing': {
639
+ inherit: true,
640
+ initial: 0,
641
+ values: {
642
+ normal: 0
643
+ }
644
+ },
645
+ 'letter-spacing': {
646
+ inherit: true,
647
+ initial: 0,
648
+ values: {
649
+ normal: 0
650
+ }
651
+ },
652
+ 'text-decoration': {
653
+ inherit: false,
654
+ initial: 'none',
655
+ values: {
656
+ 'none': 'none',
657
+ 'underline': 'underline',
658
+ 'overline': 'overline',
659
+ 'line-through': 'line-through'
660
+ }
661
+ },
662
+ 'xml:space': {
663
+ inherit: true,
664
+ initial: 'default',
665
+ css: 'white-space',
666
+ values: {
667
+ 'preserve': 'preserve',
668
+ 'default': 'default',
669
+ 'pre': 'preserve',
670
+ 'pre-line': 'preserve',
671
+ 'pre-wrap': 'preserve',
672
+ 'nowrap': 'default'
673
+ }
674
+ },
675
+ 'marker-start': {
676
+ inherit: true,
677
+ initial: 'none'
678
+ },
679
+ 'marker-mid': {
680
+ inherit: true,
681
+ initial: 'none'
682
+ },
683
+ 'marker-end': {
684
+ inherit: true,
685
+ initial: 'none'
686
+ },
687
+ 'opacity': {
688
+ inherit: false,
689
+ initial: 1
690
+ },
691
+ 'transform': {
692
+ inherit: false,
693
+ initial: [1, 0, 0, 1, 0, 0]
694
+ },
695
+ 'display': {
696
+ inherit: false,
697
+ initial: 'inline',
698
+ values: {
699
+ 'none': 'none',
700
+ 'inline': 'inline',
701
+ 'block': 'inline'
702
+ }
703
+ },
704
+ 'clip-path': {
705
+ inherit: false,
706
+ initial: 'none'
707
+ },
708
+ 'mask': {
709
+ inherit: false,
710
+ initial: 'none'
711
+ },
712
+ 'overflow': {
713
+ inherit: false,
714
+ initial: 'hidden',
715
+ values: {
716
+ 'hidden': 'hidden',
717
+ 'scroll': 'hidden',
718
+ 'visible': 'visible'
719
+ }
720
+ }
721
+ };
722
+ function docBeginGroup(bbox) {
723
+ let group = new function PDFGroup() {}();
724
+ group.name = 'G' + (doc._groupCount = (doc._groupCount || 0) + 1);
725
+ group.resources = doc.ref();
726
+ group.xobj = doc.ref({
727
+ Type: 'XObject',
728
+ Subtype: 'Form',
729
+ FormType: 1,
730
+ BBox: bbox,
731
+ Group: {
732
+ S: 'Transparency',
733
+ CS: 'DeviceRGB',
734
+ I: true,
735
+ K: false
736
+ },
737
+ Resources: group.resources
738
+ });
739
+ group.xobj.write('');
740
+ group.savedMatrix = doc._ctm;
741
+ group.savedPage = doc.page;
742
+ groupStack.push(group);
743
+ doc._ctm = [1, 0, 0, 1, 0, 0];
744
+ doc.page = {
745
+ width: doc.page.width,
746
+ height: doc.page.height,
747
+ write: function (data) {
748
+ group.xobj.write(data);
749
+ },
750
+ fonts: {},
751
+ xobjects: {},
752
+ ext_gstates: {},
753
+ patterns: {}
754
+ };
755
+ return group;
756
+ }
757
+ function docEndGroup(group) {
758
+ if (group !== groupStack.pop()) {
759
+ throw 'Group not matching';
760
+ }
761
+ if (Object.keys(doc.page.fonts).length) {
762
+ group.resources.data.Font = doc.page.fonts;
763
+ }
764
+ if (Object.keys(doc.page.xobjects).length) {
765
+ group.resources.data.XObject = doc.page.xobjects;
766
+ }
767
+ if (Object.keys(doc.page.ext_gstates).length) {
768
+ group.resources.data.ExtGState = doc.page.ext_gstates;
769
+ }
770
+ if (Object.keys(doc.page.patterns).length) {
771
+ group.resources.data.Pattern = doc.page.patterns;
772
+ }
773
+ group.resources.end();
774
+ group.xobj.end();
775
+ doc._ctm = group.savedMatrix;
776
+ doc.page = group.savedPage;
777
+ }
778
+ function docInsertGroup(group) {
779
+ doc.page.xobjects[group.name] = group.xobj;
780
+ doc.addContent('/' + group.name + ' Do');
781
+ }
782
+ function docApplyMask(group, clip) {
783
+ let name = 'M' + (doc._maskCount = (doc._maskCount || 0) + 1);
784
+ let gstate = doc.ref({
785
+ Type: 'ExtGState',
786
+ CA: 1,
787
+ ca: 1,
788
+ BM: 'Normal',
789
+ SMask: {
790
+ S: 'Luminosity',
791
+ G: group.xobj,
792
+ BC: clip ? [0, 0, 0] : [1, 1, 1]
793
+ }
794
+ });
795
+ gstate.end();
796
+ doc.page.ext_gstates[name] = gstate;
797
+ doc.addContent('/' + name + ' gs');
798
+ }
799
+ function docCreatePattern(group, dx, dy, matrix) {
800
+ let pattern = new function PDFPattern() {}();
801
+ pattern.group = group;
802
+ pattern.dx = dx;
803
+ pattern.dy = dy;
804
+ pattern.matrix = matrix || [1, 0, 0, 1, 0, 0];
805
+ return pattern;
806
+ }
807
+ function docUsePattern(pattern, stroke) {
808
+ let name = 'P' + (doc._patternCount = (doc._patternCount || 0) + 1);
809
+ let ref = doc.ref({
810
+ Type: 'Pattern',
811
+ PatternType: 1,
812
+ PaintType: 1,
813
+ TilingType: 2,
814
+ BBox: [0, 0, pattern.dx, pattern.dy],
815
+ XStep: pattern.dx,
816
+ YStep: pattern.dy,
817
+ Matrix: multiplyMatrix(doc._ctm, pattern.matrix),
818
+ Resources: {
819
+ ProcSet: ['PDF', 'Text', 'ImageB', 'ImageC', 'ImageI'],
820
+ XObject: function () {
821
+ let temp = {};
822
+ temp[pattern.group.name] = pattern.group.xobj;
823
+ return temp;
824
+ }()
825
+ }
826
+ });
827
+ ref.write('/' + pattern.group.name + ' Do');
828
+ ref.end();
829
+ doc.page.patterns[name] = ref;
830
+ if (stroke) {
831
+ doc.addContent('/Pattern CS');
832
+ doc.addContent('/' + name + ' SCN');
833
+ } else {
834
+ doc.addContent('/Pattern cs');
835
+ doc.addContent('/' + name + ' scn');
836
+ }
837
+ }
838
+ function docBeginText(font, size) {
839
+ if (!doc.page.fonts[font.id]) {
840
+ doc.page.fonts[font.id] = font.ref();
841
+ }
842
+ doc.addContent('BT').addContent('/' + font.id + ' ' + size + ' Tf');
843
+ }
844
+ function docSetTextMatrix(a, b, c, d, e, f) {
845
+ doc.addContent(validateNumber(a) + ' ' + validateNumber(b) + ' ' + validateNumber(-c) + ' ' + validateNumber(-d) + ' ' + validateNumber(e) + ' ' + validateNumber(f) + ' Tm');
846
+ }
847
+ function docSetTextMode(fill, stroke) {
848
+ let mode = fill && stroke ? 2 : stroke ? 1 : fill ? 0 : 3;
849
+ doc.addContent(mode + ' Tr');
850
+ }
851
+ function docWriteGlyph(glyph) {
852
+ doc.addContent('<' + glyph + '> Tj');
853
+ }
854
+ function docEndText() {
855
+ doc.addContent('ET');
856
+ }
857
+ function docFillColor(color) {
858
+ if (color[0].constructor.name === 'PDFPattern') {
859
+ doc.fillOpacity(color[1]);
860
+ docUsePattern(color[0], false);
861
+ } else {
862
+ doc.fillColor(color[0], color[1]);
863
+ }
864
+ }
865
+ function docStrokeColor(color) {
866
+ if (color[0].constructor.name === 'PDFPattern') {
867
+ doc.strokeOpacity(color[1]);
868
+ docUsePattern(color[0], true);
869
+ } else {
870
+ doc.strokeColor(color[0], color[1]);
871
+ }
872
+ }
873
+ function docInsertLink(x, y, w, h, url) {
874
+ let ref = doc.ref({
875
+ Type: 'Annot',
876
+ Subtype: 'Link',
877
+ Rect: [x, y, w, h],
878
+ Border: [0, 0, 0],
879
+ A: {
880
+ S: 'URI',
881
+ URI: new String(url)
882
+ }
883
+ });
884
+ ref.end();
885
+ links.push(ref);
886
+ }
887
+ function parseXml(xml) {
888
+ let SvgNode = function (tag, type, value, error) {
889
+ this.error = error;
890
+ this.nodeName = tag;
891
+ this.nodeValue = value;
892
+ this.nodeType = type;
893
+ this.attributes = Object.create(null);
894
+ this.childNodes = [];
895
+ this.parentNode = null;
896
+ this.id = '';
897
+ this.textContent = '';
898
+ this.classList = [];
899
+ };
900
+ SvgNode.prototype.getAttribute = function (attr) {
901
+ return this.attributes[attr] != null ? this.attributes[attr] : null;
902
+ };
903
+ SvgNode.prototype.getElementById = function (id) {
904
+ let result = null;
905
+ (function recursive(node) {
906
+ if (result) {
907
+ return;
908
+ }
909
+ if (node.nodeType === 1) {
910
+ if (node.id === id) {
911
+ result = node;
912
+ }
913
+ for (let i = 0; i < node.childNodes.length; i++) {
914
+ recursive(node.childNodes[i]);
915
+ }
916
+ }
917
+ })(this);
918
+ return result;
919
+ };
920
+ SvgNode.prototype.getElementsByTagName = function (tag) {
921
+ let result = [];
922
+ (function recursive(node) {
923
+ if (node.nodeType === 1) {
924
+ if (node.nodeName === tag) {
925
+ result.push(node);
926
+ }
927
+ for (let i = 0; i < node.childNodes.length; i++) {
928
+ recursive(node.childNodes[i]);
929
+ }
930
+ }
931
+ })(this);
932
+ return result;
933
+ };
934
+ let parser = new StringParser(xml.trim()),
935
+ result,
936
+ child,
937
+ error = false;
938
+ let recursive = function () {
939
+ let temp, child;
940
+ if (temp = parser.match(/^<([\w:.-]+)\s*/, true)) {
941
+ // Opening tag
942
+ let node = new SvgNode(temp[1], 1, null, error);
943
+ while (temp = parser.match(/^([\w:.-]+)(?:\s*=\s*"([^"]*)"|\s*=\s*'([^']*)')?\s*/, true)) {
944
+ // Attribute
945
+ let attr = temp[1],
946
+ value = decodeEntities(temp[2] || temp[3] || '');
947
+ if (!node.attributes[attr]) {
948
+ node.attributes[attr] = value;
949
+ if (attr === 'id') {
950
+ node.id = value;
951
+ }
952
+ if (attr === 'class') {
953
+ node.classList = value.split(' ');
954
+ }
955
+ } else {
956
+ warningCallback('parseXml: duplicate attribute "' + attr + '"');
957
+ error = true;
958
+ }
959
+ }
960
+ if (parser.match(/^>/)) {
961
+ // End of opening tag
962
+ while (child = recursive()) {
963
+ node.childNodes.push(child);
964
+ child.parentNode = node;
965
+ node.textContent += child.nodeType === 3 || child.nodeType === 4 ? child.nodeValue : child.textContent;
966
+ }
967
+ if (temp = parser.match(/^<\/([\w:.-]+)\s*>/, true)) {
968
+ // Closing tag
969
+ if (temp[1] === node.nodeName) {
970
+ return node;
971
+ } else {
972
+ warningCallback('parseXml: tag not matching, opening "' + node.nodeName + '" & closing "' + temp[1] + '"');
973
+ error = true;
974
+ return node;
975
+ }
976
+ } else {
977
+ warningCallback('parseXml: tag not matching, opening "' + node.nodeName + '" & not closing');
978
+ error = true;
979
+ return node;
980
+ }
981
+ } else if (parser.match(/^\/>/)) {
982
+ // Self-closing tag
983
+ return node;
984
+ } else {
985
+ warningCallback('parseXml: tag could not be parsed "' + node.nodeName + '"');
986
+ error = true;
987
+ }
988
+ } else if (temp = parser.match(/^<!--[\s\S]*?-->/)) {
989
+ // Comment
990
+ return new SvgNode(null, 8, temp, error);
991
+ } else if (temp = parser.match(/^<\?[\s\S]*?\?>/)) {
992
+ // Processing instructions
993
+ return new SvgNode(null, 7, temp, error);
994
+ } else if (temp = parser.match(/^<!DOCTYPE\s*([\s\S]*?)>/)) {
995
+ // Doctype
996
+ return new SvgNode(null, 10, temp, error);
997
+ } else if (temp = parser.match(/^<!\[CDATA\[([\s\S]*?)\]\]>/, true)) {
998
+ // Cdata node
999
+ return new SvgNode('#cdata-section', 4, temp[1], error);
1000
+ } else if (temp = parser.match(/^([^<]+)/, true)) {
1001
+ // Text node
1002
+ return new SvgNode('#text', 3, decodeEntities(temp[1]), error);
1003
+ }
1004
+ };
1005
+ while (child = recursive()) {
1006
+ if (child.nodeType === 1 && !result) {
1007
+ result = child;
1008
+ } else if (child.nodeType === 1 || child.nodeType === 3 && child.nodeValue.trim() !== '') {
1009
+ warningCallback('parseXml: data after document end has been discarded');
1010
+ }
1011
+ }
1012
+ if (parser.matchAll()) {
1013
+ warningCallback('parseXml: parsing error');
1014
+ }
1015
+ return result;
1016
+ }
1017
+ ;
1018
+ function decodeEntities(str) {
1019
+ return str.replace(/&(?:#([0-9]+)|#[xX]([0-9A-Fa-f]+)|([0-9A-Za-z]+));/g, function (mt, m0, m1, m2) {
1020
+ if (m0) {
1021
+ return String.fromCharCode(parseInt(m0, 10));
1022
+ } else if (m1) {
1023
+ return String.fromCharCode(parseInt(m1, 16));
1024
+ } else if (m2 && Entities[m2]) {
1025
+ return String.fromCharCode(Entities[m2]);
1026
+ } else {
1027
+ return mt;
1028
+ }
1029
+ });
1030
+ }
1031
+ function parseColor(raw) {
1032
+ let temp, result;
1033
+ raw = (raw || '').trim();
1034
+ if (temp = NamedColors[raw]) {
1035
+ result = [temp.slice(), 1];
1036
+ } else if (temp = raw.match(/^rgba\(\s*([0-9]+)\s*,\s*([0-9]+)\s*,\s*([0-9]+)\s*,\s*([0-9.]+)\s*\)$/i)) {
1037
+ temp[1] = parseInt(temp[1]);
1038
+ temp[2] = parseInt(temp[2]);
1039
+ temp[3] = parseInt(temp[3]);
1040
+ temp[4] = parseFloat(temp[4]);
1041
+ if (temp[1] < 256 && temp[2] < 256 && temp[3] < 256 && temp[4] <= 1) {
1042
+ result = [temp.slice(1, 4), temp[4]];
1043
+ }
1044
+ } else if (temp = raw.match(/^rgb\(\s*([0-9]+)\s*,\s*([0-9]+)\s*,\s*([0-9]+)\s*\)$/i)) {
1045
+ temp[1] = parseInt(temp[1]);
1046
+ temp[2] = parseInt(temp[2]);
1047
+ temp[3] = parseInt(temp[3]);
1048
+ if (temp[1] < 256 && temp[2] < 256 && temp[3] < 256) {
1049
+ result = [temp.slice(1, 4), 1];
1050
+ }
1051
+ } else if (temp = raw.match(/^rgb\(\s*([0-9.]+)%\s*,\s*([0-9.]+)%\s*,\s*([0-9.]+)%\s*\)$/i)) {
1052
+ temp[1] = 2.55 * parseFloat(temp[1]);
1053
+ temp[2] = 2.55 * parseFloat(temp[2]);
1054
+ temp[3] = 2.55 * parseFloat(temp[3]);
1055
+ if (temp[1] < 256 && temp[2] < 256 && temp[3] < 256) {
1056
+ result = [temp.slice(1, 4), 1];
1057
+ }
1058
+ } else if (temp = raw.match(/^#([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})$/i)) {
1059
+ result = [[parseInt(temp[1], 16), parseInt(temp[2], 16), parseInt(temp[3], 16)], 1];
1060
+ } else if (temp = raw.match(/^#([0-9a-f])([0-9a-f])([0-9a-f])$/i)) {
1061
+ result = [[0x11 * parseInt(temp[1], 16), 0x11 * parseInt(temp[2], 16), 0x11 * parseInt(temp[3], 16)], 1];
1062
+ }
1063
+ return colorCallback ? colorCallback(result, raw) : result;
1064
+ }
1065
+ function opacityToColor(color, opacity, isMask) {
1066
+ let newColor = color[0].slice(),
1067
+ newOpacity = color[1] * opacity;
1068
+ if (isMask) {
1069
+ for (let i = 0; i < color.length; i++) {
1070
+ newColor[i] *= newOpacity;
1071
+ }
1072
+ return [newColor, 1];
1073
+ } else {
1074
+ return [newColor, newOpacity];
1075
+ }
1076
+ }
1077
+ function multiplyMatrix() {
1078
+ function multiply(a, b) {
1079
+ return [a[0] * b[0] + a[2] * b[1], a[1] * b[0] + a[3] * b[1], a[0] * b[2] + a[2] * b[3], a[1] * b[2] + a[3] * b[3], a[0] * b[4] + a[2] * b[5] + a[4], a[1] * b[4] + a[3] * b[5] + a[5]];
1080
+ }
1081
+ let result = arguments[0];
1082
+ for (let i = 1; i < arguments.length; i++) {
1083
+ result = multiply(result, arguments[i]);
1084
+ }
1085
+ return result;
1086
+ }
1087
+ function transformPoint(p, m) {
1088
+ return [m[0] * p[0] + m[2] * p[1] + m[4], m[1] * p[0] + m[3] * p[1] + m[5]];
1089
+ }
1090
+ function getGlobalMatrix() {
1091
+ let ctm = doc._ctm;
1092
+ for (let i = groupStack.length - 1; i >= 0; i--) {
1093
+ ctm = multiplyMatrix(groupStack[i].savedMatrix, ctm);
1094
+ }
1095
+ return ctm;
1096
+ }
1097
+ function getPageBBox() {
1098
+ return new SvgShape().M(0, 0).L(doc.page.width, 0).L(doc.page.width, doc.page.height).L(0, doc.page.height).transform(inverseMatrix(getGlobalMatrix())).getBoundingBox();
1099
+ }
1100
+ function inverseMatrix(m) {
1101
+ let dt = m[0] * m[3] - m[1] * m[2];
1102
+ return [m[3] / dt, -m[1] / dt, -m[2] / dt, m[0] / dt, (m[2] * m[5] - m[3] * m[4]) / dt, (m[1] * m[4] - m[0] * m[5]) / dt];
1103
+ }
1104
+ function validateMatrix(m) {
1105
+ let m0 = validateNumber(m[0]),
1106
+ m1 = validateNumber(m[1]),
1107
+ m2 = validateNumber(m[2]),
1108
+ m3 = validateNumber(m[3]),
1109
+ m4 = validateNumber(m[4]),
1110
+ m5 = validateNumber(m[5]);
1111
+ if (isNotEqual(m0 * m3 - m1 * m2, 0)) {
1112
+ return [m0, m1, m2, m3, m4, m5];
1113
+ }
1114
+ }
1115
+ function solveEquation(curve) {
1116
+ let a = curve[2] || 0,
1117
+ b = curve[1] || 0,
1118
+ c = curve[0] || 0;
1119
+ if (isEqual(a, 0) && isEqual(b, 0)) {
1120
+ return [];
1121
+ } else if (isEqual(a, 0)) {
1122
+ return [-c / b];
1123
+ } else {
1124
+ let d = b * b - 4 * a * c;
1125
+ if (isNotEqual(d, 0) && d > 0) {
1126
+ return [(-b + Math.sqrt(d)) / (2 * a), (-b - Math.sqrt(d)) / (2 * a)];
1127
+ } else if (isEqual(d, 0)) {
1128
+ return [-b / (2 * a)];
1129
+ } else {
1130
+ return [];
1131
+ }
1132
+ }
1133
+ }
1134
+ function getCurveValue(t, curve) {
1135
+ return (curve[0] || 0) + (curve[1] || 0) * t + (curve[2] || 0) * t * t + (curve[3] || 0) * t * t * t;
1136
+ }
1137
+ function isEqual(number, ref) {
1138
+ return Math.abs(number - ref) < 1e-10;
1139
+ }
1140
+ function isNotEqual(number, ref) {
1141
+ return Math.abs(number - ref) >= 1e-10;
1142
+ }
1143
+ function validateNumber(n) {
1144
+ return n > -1e21 && n < 1e21 ? Math.round(n * 1e6) / 1e6 : 0;
1145
+ }
1146
+ function isArrayLike(v) {
1147
+ return typeof v === 'object' && v !== null && typeof v.length === 'number';
1148
+ }
1149
+ function parseTranform(v) {
1150
+ let parser = new StringParser((v || '').trim()),
1151
+ result = [1, 0, 0, 1, 0, 0],
1152
+ temp;
1153
+ while (temp = parser.match(/^([A-Za-z]+)\s*[(]([^(]+)[)]/, true)) {
1154
+ let func = temp[1],
1155
+ nums = [],
1156
+ parser2 = new StringParser(temp[2].trim()),
1157
+ temp2;
1158
+ while (temp2 = parser2.matchNumber()) {
1159
+ nums.push(Number(temp2));
1160
+ parser2.matchSeparator();
1161
+ }
1162
+ if (func === 'matrix' && nums.length === 6) {
1163
+ result = multiplyMatrix(result, [nums[0], nums[1], nums[2], nums[3], nums[4], nums[5]]);
1164
+ } else if (func === 'translate' && nums.length === 2) {
1165
+ result = multiplyMatrix(result, [1, 0, 0, 1, nums[0], nums[1]]);
1166
+ } else if (func === 'translate' && nums.length === 1) {
1167
+ result = multiplyMatrix(result, [1, 0, 0, 1, nums[0], 0]);
1168
+ } else if (func === 'scale' && nums.length === 2) {
1169
+ result = multiplyMatrix(result, [nums[0], 0, 0, nums[1], 0, 0]);
1170
+ } else if (func === 'scale' && nums.length === 1) {
1171
+ result = multiplyMatrix(result, [nums[0], 0, 0, nums[0], 0, 0]);
1172
+ } else if (func === 'rotate' && nums.length === 3) {
1173
+ let a = nums[0] * Math.PI / 180;
1174
+ result = multiplyMatrix(result, [1, 0, 0, 1, nums[1], nums[2]], [Math.cos(a), Math.sin(a), -Math.sin(a), Math.cos(a), 0, 0], [1, 0, 0, 1, -nums[1], -nums[2]]);
1175
+ } else if (func === 'rotate' && nums.length === 1) {
1176
+ let a = nums[0] * Math.PI / 180;
1177
+ result = multiplyMatrix(result, [Math.cos(a), Math.sin(a), -Math.sin(a), Math.cos(a), 0, 0]);
1178
+ } else if (func === 'skewX' && nums.length === 1) {
1179
+ let a = nums[0] * Math.PI / 180;
1180
+ result = multiplyMatrix(result, [1, 0, Math.tan(a), 1, 0, 0]);
1181
+ } else if (func === 'skewY' && nums.length === 1) {
1182
+ let a = nums[0] * Math.PI / 180;
1183
+ result = multiplyMatrix(result, [1, Math.tan(a), 0, 1, 0, 0]);
1184
+ } else {
1185
+ return;
1186
+ }
1187
+ parser.matchSeparator();
1188
+ }
1189
+ if (parser.matchAll()) {
1190
+ return;
1191
+ }
1192
+ return result;
1193
+ }
1194
+ function parseAspectRatio(aspectRatio, availWidth, availHeight, elemWidth, elemHeight, initAlign) {
1195
+ let temp = (aspectRatio || '').trim().match(/^(none)$|^x(Min|Mid|Max)Y(Min|Mid|Max)(?:\s+(meet|slice))?$/) || [],
1196
+ ratioType = temp[1] || temp[4] || 'meet',
1197
+ xAlign = temp[2] || 'Mid',
1198
+ yAlign = temp[3] || 'Mid',
1199
+ scaleX = availWidth / elemWidth,
1200
+ scaleY = availHeight / elemHeight,
1201
+ dx = {
1202
+ 'Min': 0,
1203
+ 'Mid': 0.5,
1204
+ 'Max': 1
1205
+ }[xAlign] - (initAlign || 0),
1206
+ dy = {
1207
+ 'Min': 0,
1208
+ 'Mid': 0.5,
1209
+ 'Max': 1
1210
+ }[yAlign] - (initAlign || 0);
1211
+ if (ratioType === 'slice') {
1212
+ scaleY = scaleX = Math.max(scaleX, scaleY);
1213
+ } else if (ratioType === 'meet') {
1214
+ scaleY = scaleX = Math.min(scaleX, scaleY);
1215
+ }
1216
+ return [scaleX, 0, 0, scaleY, dx * (availWidth - elemWidth * scaleX), dy * (availHeight - elemHeight * scaleY)];
1217
+ }
1218
+ function parseStyleAttr(v) {
1219
+ let result = Object.create(null);
1220
+ v = (v || '').trim().split(/;/);
1221
+ for (let i = 0; i < v.length; i++) {
1222
+ let key = (v[i].split(':')[0] || '').trim(),
1223
+ value = (v[i].split(':')[1] || '').trim();
1224
+ if (key) {
1225
+ result[key] = value;
1226
+ }
1227
+ }
1228
+ if (result['marker']) {
1229
+ if (!result['marker-start']) {
1230
+ result['marker-start'] = result['marker'];
1231
+ }
1232
+ if (!result['marker-mid']) {
1233
+ result['marker-mid'] = result['marker'];
1234
+ }
1235
+ if (!result['marker-end']) {
1236
+ result['marker-end'] = result['marker'];
1237
+ }
1238
+ }
1239
+ if (result['font']) {
1240
+ let fontFamily = null,
1241
+ fontSize = null,
1242
+ fontStyle = "normal",
1243
+ fontWeight = "normal",
1244
+ fontVariant = "normal";
1245
+ let parts = result['font'].split(/\s+/);
1246
+ for (let i = 0; i < parts.length; i++) {
1247
+ switch (parts[i]) {
1248
+ case "normal":
1249
+ break;
1250
+ case "italic":
1251
+ case "oblique":
1252
+ fontStyle = parts[i];
1253
+ break;
1254
+ case "small-caps":
1255
+ fontVariant = parts[i];
1256
+ break;
1257
+ case "bold":
1258
+ case "bolder":
1259
+ case "lighter":
1260
+ case "100":
1261
+ case "200":
1262
+ case "300":
1263
+ case "400":
1264
+ case "500":
1265
+ case "600":
1266
+ case "700":
1267
+ case "800":
1268
+ case "900":
1269
+ fontWeight = parts[i];
1270
+ break;
1271
+ default:
1272
+ if (!fontSize) {
1273
+ fontSize = parts[i].split('/')[0];
1274
+ } else {
1275
+ if (!fontFamily) {
1276
+ fontFamily = parts[i];
1277
+ } else {
1278
+ fontFamily += ' ' + parts[i];
1279
+ }
1280
+ }
1281
+ break;
1282
+ }
1283
+ }
1284
+ if (!result['font-style']) {
1285
+ result['font-style'] = fontStyle;
1286
+ }
1287
+ if (!result['font-variant']) {
1288
+ result['font-variant'] = fontVariant;
1289
+ }
1290
+ if (!result['font-weight']) {
1291
+ result['font-weight'] = fontWeight;
1292
+ }
1293
+ if (!result['font-size']) {
1294
+ result['font-size'] = fontSize;
1295
+ }
1296
+ if (!result['font-family']) {
1297
+ result['font-family'] = fontFamily;
1298
+ }
1299
+ }
1300
+ return result;
1301
+ }
1302
+ function parseSelector(v) {
1303
+ let parts = v.split(/(?=[.#])/g),
1304
+ ids = [],
1305
+ classes = [],
1306
+ tags = [],
1307
+ temp;
1308
+ for (let i = 0; i < parts.length; i++) {
1309
+ if (temp = parts[i].match(/^[#]([_A-Za-z0-9-]+)$/)) {
1310
+ ids.push(temp[1]);
1311
+ } else if (temp = parts[i].match(/^[.]([_A-Za-z0-9-]+)$/)) {
1312
+ classes.push(temp[1]);
1313
+ } else if (temp = parts[i].match(/^([_A-Za-z0-9-]+)$/)) {
1314
+ tags.push(temp[1]);
1315
+ } else if (parts[i] !== '*') {
1316
+ return;
1317
+ }
1318
+ }
1319
+ return {
1320
+ tags: tags,
1321
+ ids: ids,
1322
+ classes: classes,
1323
+ specificity: ids.length * 10000 + classes.length * 100 + tags.length
1324
+ };
1325
+ }
1326
+ function parseStyleSheet(v) {
1327
+ let parser = new StringParser(v.trim()),
1328
+ rules = [],
1329
+ rule;
1330
+ while (rule = parser.match(/^\s*([^\{\}]*?)\s*\{([^\{\}]*?)\}/, true)) {
1331
+ let selectors = rule[1].split(/\s*,\s*/g),
1332
+ css = parseStyleAttr(rule[2]);
1333
+ for (let i = 0; i < selectors.length; i++) {
1334
+ let selector = parseSelector(selectors[i]);
1335
+ if (selector) {
1336
+ rules.push({
1337
+ selector: selector,
1338
+ css: css
1339
+ });
1340
+ }
1341
+ }
1342
+ }
1343
+ return rules;
1344
+ }
1345
+ function matchesSelector(elem, selector) {
1346
+ if (elem.nodeType !== 1) {
1347
+ return false;
1348
+ }
1349
+ for (let i = 0; i < selector.tags.length; i++) {
1350
+ if (selector.tags[i] !== elem.nodeName) {
1351
+ return false;
1352
+ }
1353
+ }
1354
+ for (let i = 0; i < selector.ids.length; i++) {
1355
+ if (selector.ids[i] !== elem.id) {
1356
+ return false;
1357
+ }
1358
+ }
1359
+ for (let i = 0; i < selector.classes.length; i++) {
1360
+ if (elem.classList.indexOf(selector.classes[i]) === -1) {
1361
+ return false;
1362
+ }
1363
+ }
1364
+ return true;
1365
+ }
1366
+ function getStyle(elem) {
1367
+ let result = Object.create(null);
1368
+ let specificities = Object.create(null);
1369
+ for (let i = 0; i < styleRules.length; i++) {
1370
+ let rule = styleRules[i];
1371
+ if (matchesSelector(elem, rule.selector)) {
1372
+ for (let key in rule.css) {
1373
+ if (!(specificities[key] > rule.selector.specificity)) {
1374
+ result[key] = rule.css[key];
1375
+ specificities[key] = rule.selector.specificity;
1376
+ }
1377
+ }
1378
+ }
1379
+ }
1380
+ return result;
1381
+ }
1382
+ function combineArrays(array1, array2) {
1383
+ return array1.concat(array2.slice(array1.length));
1384
+ }
1385
+ function getAscent(font, size) {
1386
+ return Math.max(font.ascender, (font.bbox[3] || font.bbox.maxY) * (font.scale || 1)) * size / 1000;
1387
+ }
1388
+ function getDescent(font, size) {
1389
+ return Math.min(font.descender, (font.bbox[1] || font.bbox.minY) * (font.scale || 1)) * size / 1000;
1390
+ }
1391
+ function getXHeight(font, size) {
1392
+ return (font.xHeight || 0.5 * (font.ascender - font.descender)) * size / 1000;
1393
+ }
1394
+ function getBaseline(font, size, baseline, shift) {
1395
+ let dy1, dy2;
1396
+ switch (baseline) {
1397
+ case 'middle':
1398
+ dy1 = 0.5 * getXHeight(font, size);
1399
+ break;
1400
+ case 'central':
1401
+ dy1 = 0.5 * (getDescent(font, size) + getAscent(font, size));
1402
+ break;
1403
+ case 'after-edge':
1404
+ case 'text-after-edge':
1405
+ dy1 = getDescent(font, size);
1406
+ break;
1407
+ case 'alphabetic':
1408
+ case 'auto':
1409
+ case 'baseline':
1410
+ dy1 = 0;
1411
+ break;
1412
+ case 'mathematical':
1413
+ dy1 = 0.5 * getAscent(font, size);
1414
+ break;
1415
+ case 'hanging':
1416
+ dy1 = 0.8 * getAscent(font, size);
1417
+ break;
1418
+ case 'before-edge':
1419
+ case 'text-before-edge':
1420
+ dy1 = getAscent(font, size);
1421
+ break;
1422
+ default:
1423
+ dy1 = 0;
1424
+ break;
1425
+ }
1426
+ switch (shift) {
1427
+ case 'baseline':
1428
+ dy2 = 0;
1429
+ break;
1430
+ case 'super':
1431
+ dy2 = 0.6 * size;
1432
+ break;
1433
+ case 'sub':
1434
+ dy2 = -0.6 * size;
1435
+ break;
1436
+ default:
1437
+ dy2 = shift;
1438
+ break;
1439
+ }
1440
+ return dy1 - dy2;
1441
+ }
1442
+ function getTextPos(font, size, text) {
1443
+ let encoded = font.encode('' + text),
1444
+ hex = encoded[0],
1445
+ pos = encoded[1],
1446
+ data = [];
1447
+ for (let i = 0; i < hex.length; i++) {
1448
+ let unicode = font.unicode ? font.unicode[parseInt(hex[i], 16)] : [text.charCodeAt(i)];
1449
+ data.push({
1450
+ glyph: hex[i],
1451
+ unicode: unicode,
1452
+ width: pos[i].advanceWidth * size / 1000,
1453
+ xOffset: pos[i].xOffset * size / 1000,
1454
+ yOffset: pos[i].yOffset * size / 1000,
1455
+ xAdvance: pos[i].xAdvance * size / 1000,
1456
+ yAdvance: pos[i].yAdvance * size / 1000
1457
+ });
1458
+ }
1459
+ return data;
1460
+ }
1461
+ function createSVGElement(obj, inherits) {
1462
+ switch (obj.nodeName) {
1463
+ case 'use':
1464
+ return new SvgElemUse(obj, inherits);
1465
+ case 'symbol':
1466
+ return new SvgElemSymbol(obj, inherits);
1467
+ case 'g':
1468
+ return new SvgElemGroup(obj, inherits);
1469
+ case 'a':
1470
+ return new SvgElemLink(obj, inherits);
1471
+ case 'svg':
1472
+ return new SvgElemSvg(obj, inherits);
1473
+ case 'image':
1474
+ return new SVGElemImage(obj, inherits);
1475
+ case 'rect':
1476
+ return new SvgElemRect(obj, inherits);
1477
+ case 'circle':
1478
+ return new SvgElemCircle(obj, inherits);
1479
+ case 'ellipse':
1480
+ return new SvgElemEllipse(obj, inherits);
1481
+ case 'line':
1482
+ return new SvgElemLine(obj, inherits);
1483
+ case 'polyline':
1484
+ return new SvgElemPolyline(obj, inherits);
1485
+ case 'polygon':
1486
+ return new SvgElemPolygon(obj, inherits);
1487
+ case 'path':
1488
+ return new SvgElemPath(obj, inherits);
1489
+ case 'text':
1490
+ return new SvgElemText(obj, inherits);
1491
+ case 'tspan':
1492
+ return new SvgElemTspan(obj, inherits);
1493
+ case 'textPath':
1494
+ return new SvgElemTextPath(obj, inherits);
1495
+ case '#text':
1496
+ case '#cdata-section':
1497
+ return new SvgElemTextNode(obj, inherits);
1498
+ default:
1499
+ return new SvgElem(obj, inherits);
1500
+ }
1501
+ }
1502
+ var StringParser = function (str) {
1503
+ this.match = function (exp, all) {
1504
+ let temp = str.match(exp);
1505
+ if (!temp || temp.index !== 0) {
1506
+ return;
1507
+ }
1508
+ str = str.substring(temp[0].length);
1509
+ return all ? temp : temp[0];
1510
+ };
1511
+ this.matchSeparator = function () {
1512
+ return this.match(/^(?:\s*,\s*|\s*|)/);
1513
+ };
1514
+ this.matchSpace = function () {
1515
+ return this.match(/^(?:\s*)/);
1516
+ };
1517
+ this.matchLengthUnit = function () {
1518
+ return this.match(/^(?:px|pt|cm|mm|in|pc|em|ex|%|)/);
1519
+ };
1520
+ this.matchNumber = function () {
1521
+ return this.match(/^(?:[-+]?(?:[0-9]+[.][0-9]+|[0-9]+[.]|[.][0-9]+|[0-9]+)(?:[eE][-+]?[0-9]+)?)/);
1522
+ };
1523
+ this.matchAll = function () {
1524
+ return this.match(/^[\s\S]+/);
1525
+ };
1526
+ };
1527
+ var BezierSegment = function (p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y) {
1528
+ let divisions = 6 * precision;
1529
+ let equationX = [p1x, -3 * p1x + 3 * c1x, 3 * p1x - 6 * c1x + 3 * c2x, -p1x + 3 * c1x - 3 * c2x + p2x];
1530
+ let equationY = [p1y, -3 * p1y + 3 * c1y, 3 * p1y - 6 * c1y + 3 * c2y, -p1y + 3 * c1y - 3 * c2y + p2y];
1531
+ let derivativeX = [-3 * p1x + 3 * c1x, 6 * p1x - 12 * c1x + 6 * c2x, -3 * p1x + 9 * c1x - 9 * c2x + 3 * p2x];
1532
+ let derivativeY = [-3 * p1y + 3 * c1y, 6 * p1y - 12 * c1y + 6 * c2y, -3 * p1y + 9 * c1y - 9 * c2y + 3 * p2y];
1533
+ let lengthMap = [0];
1534
+ for (let i = 1; i <= divisions; i++) {
1535
+ let t = (i - 0.5) / divisions;
1536
+ let dx = getCurveValue(t, derivativeX) / divisions,
1537
+ dy = getCurveValue(t, derivativeY) / divisions,
1538
+ l = Math.sqrt(dx * dx + dy * dy);
1539
+ lengthMap[i] = lengthMap[i - 1] + l;
1540
+ }
1541
+ this.totalLength = lengthMap[divisions];
1542
+ this.startPoint = [p1x, p1y, isEqual(p1x, c1x) && isEqual(p1y, c1y) ? Math.atan2(c2y - c1y, c2x - c1x) : Math.atan2(c1y - p1y, c1x - p1x)];
1543
+ this.endPoint = [p2x, p2y, isEqual(c2x, p2x) && isEqual(c2y, p2y) ? Math.atan2(c2y - c1y, c2x - c1x) : Math.atan2(p2y - c2y, p2x - c2x)];
1544
+ this.getBoundingBox = function () {
1545
+ let temp;
1546
+ let minX = getCurveValue(0, equationX),
1547
+ minY = getCurveValue(0, equationY),
1548
+ maxX = getCurveValue(1, equationX),
1549
+ maxY = getCurveValue(1, equationY);
1550
+ if (minX > maxX) {
1551
+ temp = maxX;
1552
+ maxX = minX;
1553
+ minX = temp;
1554
+ }
1555
+ if (minY > maxY) {
1556
+ temp = maxY;
1557
+ maxY = minY;
1558
+ minY = temp;
1559
+ }
1560
+ let rootsX = solveEquation(derivativeX);
1561
+ for (let i = 0; i < rootsX.length; i++) {
1562
+ if (rootsX[i] >= 0 && rootsX[i] <= 1) {
1563
+ let x = getCurveValue(rootsX[i], equationX);
1564
+ if (x < minX) {
1565
+ minX = x;
1566
+ }
1567
+ if (x > maxX) {
1568
+ maxX = x;
1569
+ }
1570
+ }
1571
+ }
1572
+ let rootsY = solveEquation(derivativeY);
1573
+ for (let i = 0; i < rootsY.length; i++) {
1574
+ if (rootsY[i] >= 0 && rootsY[i] <= 1) {
1575
+ let y = getCurveValue(rootsY[i], equationY);
1576
+ if (y < minY) {
1577
+ minY = y;
1578
+ }
1579
+ if (y > maxY) {
1580
+ maxY = y;
1581
+ }
1582
+ }
1583
+ }
1584
+ return [minX, minY, maxX, maxY];
1585
+ };
1586
+ this.getPointAtLength = function (l) {
1587
+ if (isEqual(l, 0)) {
1588
+ return this.startPoint;
1589
+ }
1590
+ if (isEqual(l, this.totalLength)) {
1591
+ return this.endPoint;
1592
+ }
1593
+ if (l < 0 || l > this.totalLength) {
1594
+ return;
1595
+ }
1596
+ for (let i = 1; i <= divisions; i++) {
1597
+ let l1 = lengthMap[i - 1],
1598
+ l2 = lengthMap[i];
1599
+ if (l1 <= l && l <= l2) {
1600
+ let t = (i - (l2 - l) / (l2 - l1)) / divisions,
1601
+ x = getCurveValue(t, equationX),
1602
+ y = getCurveValue(t, equationY),
1603
+ dx = getCurveValue(t, derivativeX),
1604
+ dy = getCurveValue(t, derivativeY);
1605
+ return [x, y, Math.atan2(dy, dx)];
1606
+ }
1607
+ }
1608
+ };
1609
+ };
1610
+ var LineSegment = function (p1x, p1y, p2x, p2y) {
1611
+ this.totalLength = Math.sqrt((p2x - p1x) * (p2x - p1x) + (p2y - p1y) * (p2y - p1y));
1612
+ this.startPoint = [p1x, p1y, Math.atan2(p2y - p1y, p2x - p1x)];
1613
+ this.endPoint = [p2x, p2y, Math.atan2(p2y - p1y, p2x - p1x)];
1614
+ this.getBoundingBox = function () {
1615
+ return [Math.min(this.startPoint[0], this.endPoint[0]), Math.min(this.startPoint[1], this.endPoint[1]), Math.max(this.startPoint[0], this.endPoint[0]), Math.max(this.startPoint[1], this.endPoint[1])];
1616
+ };
1617
+ this.getPointAtLength = function (l) {
1618
+ if (l >= 0 && l <= this.totalLength) {
1619
+ let r = l / this.totalLength || 0,
1620
+ x = this.startPoint[0] + r * (this.endPoint[0] - this.startPoint[0]),
1621
+ y = this.startPoint[1] + r * (this.endPoint[1] - this.startPoint[1]);
1622
+ return [x, y, this.startPoint[2]];
1623
+ }
1624
+ };
1625
+ };
1626
+ var SvgShape = function () {
1627
+ this.pathCommands = [];
1628
+ this.pathSegments = [];
1629
+ this.startPoint = null;
1630
+ this.endPoint = null;
1631
+ this.totalLength = 0;
1632
+ let startX = 0,
1633
+ startY = 0,
1634
+ currX = 0,
1635
+ currY = 0,
1636
+ lastCom,
1637
+ lastCtrlX,
1638
+ lastCtrlY;
1639
+ this.move = function (x, y) {
1640
+ startX = currX = x;
1641
+ startY = currY = y;
1642
+ return null;
1643
+ };
1644
+ this.line = function (x, y) {
1645
+ let segment = new LineSegment(currX, currY, x, y);
1646
+ currX = x;
1647
+ currY = y;
1648
+ return segment;
1649
+ };
1650
+ this.curve = function (c1x, c1y, c2x, c2y, x, y) {
1651
+ let segment = new BezierSegment(currX, currY, c1x, c1y, c2x, c2y, x, y);
1652
+ currX = x;
1653
+ currY = y;
1654
+ return segment;
1655
+ };
1656
+ this.close = function () {
1657
+ let segment = new LineSegment(currX, currY, startX, startY);
1658
+ currX = startX;
1659
+ currY = startY;
1660
+ return segment;
1661
+ };
1662
+ this.addCommand = function (data) {
1663
+ this.pathCommands.push(data);
1664
+ let segment = this[data[0]].apply(this, data.slice(3));
1665
+ if (segment) {
1666
+ segment.hasStart = data[1];
1667
+ segment.hasEnd = data[2];
1668
+ this.startPoint = this.startPoint || segment.startPoint;
1669
+ this.endPoint = segment.endPoint;
1670
+ this.pathSegments.push(segment);
1671
+ this.totalLength += segment.totalLength;
1672
+ }
1673
+ };
1674
+ this.M = function (x, y) {
1675
+ this.addCommand(['move', true, true, x, y]);
1676
+ lastCom = 'M';
1677
+ return this;
1678
+ };
1679
+ this.m = function (x, y) {
1680
+ return this.M(currX + x, currY + y);
1681
+ };
1682
+ this.Z = this.z = function () {
1683
+ this.addCommand(['close', true, true]);
1684
+ lastCom = 'Z';
1685
+ return this;
1686
+ };
1687
+ this.L = function (x, y) {
1688
+ this.addCommand(['line', true, true, x, y]);
1689
+ lastCom = 'L';
1690
+ return this;
1691
+ };
1692
+ this.l = function (x, y) {
1693
+ return this.L(currX + x, currY + y);
1694
+ };
1695
+ this.H = function (x) {
1696
+ return this.L(x, currY);
1697
+ };
1698
+ this.h = function (x) {
1699
+ return this.L(currX + x, currY);
1700
+ };
1701
+ this.V = function (y) {
1702
+ return this.L(currX, y);
1703
+ };
1704
+ this.v = function (y) {
1705
+ return this.L(currX, currY + y);
1706
+ };
1707
+ this.C = function (c1x, c1y, c2x, c2y, x, y) {
1708
+ this.addCommand(['curve', true, true, c1x, c1y, c2x, c2y, x, y]);
1709
+ lastCom = 'C';
1710
+ lastCtrlX = c2x;
1711
+ lastCtrlY = c2y;
1712
+ return this;
1713
+ };
1714
+ this.c = function (c1x, c1y, c2x, c2y, x, y) {
1715
+ return this.C(currX + c1x, currY + c1y, currX + c2x, currY + c2y, currX + x, currY + y);
1716
+ };
1717
+ this.S = function (c1x, c1y, x, y) {
1718
+ return this.C(currX + (lastCom === 'C' ? currX - lastCtrlX : 0), currY + (lastCom === 'C' ? currY - lastCtrlY : 0), c1x, c1y, x, y);
1719
+ };
1720
+ this.s = function (c1x, c1y, x, y) {
1721
+ return this.C(currX + (lastCom === 'C' ? currX - lastCtrlX : 0), currY + (lastCom === 'C' ? currY - lastCtrlY : 0), currX + c1x, currY + c1y, currX + x, currY + y);
1722
+ };
1723
+ this.Q = function (cx, cy, x, y) {
1724
+ let c1x = currX + 2 / 3 * (cx - currX),
1725
+ c1y = currY + 2 / 3 * (cy - currY),
1726
+ c2x = x + 2 / 3 * (cx - x),
1727
+ c2y = y + 2 / 3 * (cy - y);
1728
+ this.addCommand(['curve', true, true, c1x, c1y, c2x, c2y, x, y]);
1729
+ lastCom = 'Q';
1730
+ lastCtrlX = cx;
1731
+ lastCtrlY = cy;
1732
+ return this;
1733
+ };
1734
+ this.q = function (c1x, c1y, x, y) {
1735
+ return this.Q(currX + c1x, currY + c1y, currX + x, currY + y);
1736
+ };
1737
+ this.T = function (x, y) {
1738
+ return this.Q(currX + (lastCom === 'Q' ? currX - lastCtrlX : 0), currY + (lastCom === 'Q' ? currY - lastCtrlY : 0), x, y);
1739
+ };
1740
+ this.t = function (x, y) {
1741
+ return this.Q(currX + (lastCom === 'Q' ? currX - lastCtrlX : 0), currY + (lastCom === 'Q' ? currY - lastCtrlY : 0), currX + x, currY + y);
1742
+ };
1743
+ this.A = function (rx, ry, fi, fa, fs, x, y) {
1744
+ if (isEqual(rx, 0) || isEqual(ry, 0)) {
1745
+ this.addCommand(['line', true, true, x, y]);
1746
+ } else {
1747
+ fi = fi * (Math.PI / 180);
1748
+ rx = Math.abs(rx);
1749
+ ry = Math.abs(ry);
1750
+ fa = 1 * !!fa;
1751
+ fs = 1 * !!fs;
1752
+ let x1 = Math.cos(fi) * (currX - x) / 2 + Math.sin(fi) * (currY - y) / 2,
1753
+ y1 = Math.cos(fi) * (currY - y) / 2 - Math.sin(fi) * (currX - x) / 2,
1754
+ lambda = x1 * x1 / (rx * rx) + y1 * y1 / (ry * ry);
1755
+ if (lambda > 1) {
1756
+ rx *= Math.sqrt(lambda);
1757
+ ry *= Math.sqrt(lambda);
1758
+ }
1759
+ let r = Math.sqrt(Math.max(0, rx * rx * ry * ry - rx * rx * y1 * y1 - ry * ry * x1 * x1) / (rx * rx * y1 * y1 + ry * ry * x1 * x1)),
1760
+ x2 = (fa === fs ? -1 : 1) * r * rx * y1 / ry,
1761
+ y2 = (fa === fs ? 1 : -1) * r * ry * x1 / rx;
1762
+ let cx = Math.cos(fi) * x2 - Math.sin(fi) * y2 + (currX + x) / 2,
1763
+ cy = Math.sin(fi) * x2 + Math.cos(fi) * y2 + (currY + y) / 2,
1764
+ th1 = Math.atan2((y1 - y2) / ry, (x1 - x2) / rx),
1765
+ th2 = Math.atan2((-y1 - y2) / ry, (-x1 - x2) / rx);
1766
+ if (fs === 0 && th2 - th1 > 0) {
1767
+ th2 -= 2 * Math.PI;
1768
+ } else if (fs === 1 && th2 - th1 < 0) {
1769
+ th2 += 2 * Math.PI;
1770
+ }
1771
+ let segms = Math.ceil(Math.abs(th2 - th1) / (Math.PI / precision));
1772
+ for (let i = 0; i < segms; i++) {
1773
+ let th3 = th1 + i * (th2 - th1) / segms,
1774
+ th4 = th1 + (i + 1) * (th2 - th1) / segms,
1775
+ t = 4 / 3 * Math.tan((th4 - th3) / 4);
1776
+ let c1x = cx + Math.cos(fi) * rx * (Math.cos(th3) - t * Math.sin(th3)) - Math.sin(fi) * ry * (Math.sin(th3) + t * Math.cos(th3)),
1777
+ c1y = cy + Math.sin(fi) * rx * (Math.cos(th3) - t * Math.sin(th3)) + Math.cos(fi) * ry * (Math.sin(th3) + t * Math.cos(th3)),
1778
+ c2x = cx + Math.cos(fi) * rx * (Math.cos(th4) + t * Math.sin(th4)) - Math.sin(fi) * ry * (Math.sin(th4) - t * Math.cos(th4)),
1779
+ c2y = cy + Math.sin(fi) * rx * (Math.cos(th4) + t * Math.sin(th4)) + Math.cos(fi) * ry * (Math.sin(th4) - t * Math.cos(th4)),
1780
+ endX = cx + Math.cos(fi) * rx * Math.cos(th4) - Math.sin(fi) * ry * Math.sin(th4),
1781
+ endY = cy + Math.sin(fi) * rx * Math.cos(th4) + Math.cos(fi) * ry * Math.sin(th4);
1782
+ this.addCommand(['curve', i === 0, i === segms - 1, c1x, c1y, c2x, c2y, endX, endY]);
1783
+ }
1784
+ }
1785
+ lastCom = 'A';
1786
+ return this;
1787
+ };
1788
+ this.a = function (rx, ry, fi, fa, fs, x, y) {
1789
+ return this.A(rx, ry, fi, fa, fs, currX + x, currY + y);
1790
+ };
1791
+ this.path = function (d) {
1792
+ let command,
1793
+ value,
1794
+ temp,
1795
+ parser = new StringParser((d || '').trim());
1796
+ while (command = parser.match(/^[astvzqmhlcASTVZQMHLC]/)) {
1797
+ parser.matchSeparator();
1798
+ let values = [];
1799
+ while (value = PathFlags[command + values.length] ? parser.match(/^[01]/) : parser.matchNumber()) {
1800
+ parser.matchSeparator();
1801
+ if (values.length === PathArguments[command]) {
1802
+ this[command].apply(this, values);
1803
+ values = [];
1804
+ if (command === 'M') {
1805
+ command = 'L';
1806
+ } else if (command === 'm') {
1807
+ command = 'l';
1808
+ }
1809
+ }
1810
+ values.push(Number(value));
1811
+ }
1812
+ if (values.length === PathArguments[command]) {
1813
+ this[command].apply(this, values);
1814
+ } else {
1815
+ warningCallback('SvgPath: command ' + command + ' with ' + values.length + ' numbers');
1816
+ return;
1817
+ }
1818
+ }
1819
+ if (temp = parser.matchAll()) {
1820
+ warningCallback('SvgPath: unexpected string ' + temp);
1821
+ }
1822
+ return this;
1823
+ };
1824
+ this.getBoundingBox = function () {
1825
+ let bbox = [Infinity, Infinity, -Infinity, -Infinity];
1826
+ function addBounds(bbox1) {
1827
+ if (bbox1[0] < bbox[0]) {
1828
+ bbox[0] = bbox1[0];
1829
+ }
1830
+ if (bbox1[2] > bbox[2]) {
1831
+ bbox[2] = bbox1[2];
1832
+ }
1833
+ if (bbox1[1] < bbox[1]) {
1834
+ bbox[1] = bbox1[1];
1835
+ }
1836
+ if (bbox1[3] > bbox[3]) {
1837
+ bbox[3] = bbox1[3];
1838
+ }
1839
+ }
1840
+ for (let i = 0; i < this.pathSegments.length; i++) {
1841
+ addBounds(this.pathSegments[i].getBoundingBox());
1842
+ }
1843
+ if (bbox[0] === Infinity) {
1844
+ bbox[0] = 0;
1845
+ }
1846
+ if (bbox[1] === Infinity) {
1847
+ bbox[1] = 0;
1848
+ }
1849
+ if (bbox[2] === -Infinity) {
1850
+ bbox[2] = 0;
1851
+ }
1852
+ if (bbox[3] === -Infinity) {
1853
+ bbox[3] = 0;
1854
+ }
1855
+ return bbox;
1856
+ };
1857
+ this.getPointAtLength = function (l) {
1858
+ if (l >= 0 && l <= this.totalLength) {
1859
+ let temp;
1860
+ for (let i = 0; i < this.pathSegments.length; i++) {
1861
+ if (temp = this.pathSegments[i].getPointAtLength(l)) {
1862
+ return temp;
1863
+ }
1864
+ l -= this.pathSegments[i].totalLength;
1865
+ }
1866
+ return this.endPoint;
1867
+ }
1868
+ };
1869
+ this.transform = function (m) {
1870
+ this.pathSegments = [];
1871
+ this.startPoint = null;
1872
+ this.endPoint = null;
1873
+ this.totalLength = 0;
1874
+ for (let i = 0; i < this.pathCommands.length; i++) {
1875
+ let data = this.pathCommands.shift();
1876
+ for (let j = 3; j < data.length; j += 2) {
1877
+ let p = transformPoint([data[j], data[j + 1]], m);
1878
+ data[j] = p[0];
1879
+ data[j + 1] = p[1];
1880
+ }
1881
+ this.addCommand(data);
1882
+ }
1883
+ return this;
1884
+ };
1885
+ this.mergeShape = function (shape) {
1886
+ for (let i = 0; i < shape.pathCommands.length; i++) {
1887
+ this.addCommand(shape.pathCommands[i].slice());
1888
+ }
1889
+ return this;
1890
+ };
1891
+ this.clone = function () {
1892
+ return new SvgShape().mergeShape(this);
1893
+ };
1894
+ this.insertInDocument = function () {
1895
+ for (let i = 0; i < this.pathCommands.length; i++) {
1896
+ let command = this.pathCommands[i][0],
1897
+ values = this.pathCommands[i].slice(3);
1898
+ switch (command) {
1899
+ case 'move':
1900
+ doc.moveTo(values[0], values[1]);
1901
+ break;
1902
+ case 'line':
1903
+ doc.lineTo(values[0], values[1]);
1904
+ break;
1905
+ case 'curve':
1906
+ doc.bezierCurveTo(values[0], values[1], values[2], values[3], values[4], values[5]);
1907
+ break;
1908
+ case 'close':
1909
+ doc.closePath();
1910
+ break;
1911
+ }
1912
+ }
1913
+ };
1914
+ this.getSubPaths = function () {
1915
+ let subPaths = [],
1916
+ shape = new SvgShape();
1917
+ for (let i = 0; i < this.pathCommands.length; i++) {
1918
+ let data = this.pathCommands[i],
1919
+ command = this.pathCommands[i][0];
1920
+ if (command === 'move' && i !== 0) {
1921
+ subPaths.push(shape);
1922
+ shape = new SvgShape();
1923
+ }
1924
+ shape.addCommand(data);
1925
+ }
1926
+ subPaths.push(shape);
1927
+ return subPaths;
1928
+ };
1929
+ this.getMarkers = function () {
1930
+ let markers = [],
1931
+ subPaths = this.getSubPaths();
1932
+ for (let i = 0; i < subPaths.length; i++) {
1933
+ let subPath = subPaths[i],
1934
+ subPathMarkers = [];
1935
+ for (let j = 0; j < subPath.pathSegments.length; j++) {
1936
+ let segment = subPath.pathSegments[j];
1937
+ if (isNotEqual(segment.totalLength, 0) || j === 0 || j === subPath.pathSegments.length - 1) {
1938
+ if (segment.hasStart) {
1939
+ let startMarker = segment.getPointAtLength(0),
1940
+ prevEndMarker = subPathMarkers.pop();
1941
+ if (prevEndMarker) {
1942
+ startMarker[2] = 0.5 * (prevEndMarker[2] + startMarker[2]);
1943
+ }
1944
+ subPathMarkers.push(startMarker);
1945
+ }
1946
+ if (segment.hasEnd) {
1947
+ let endMarker = segment.getPointAtLength(segment.totalLength);
1948
+ subPathMarkers.push(endMarker);
1949
+ }
1950
+ }
1951
+ }
1952
+ markers = markers.concat(subPathMarkers);
1953
+ }
1954
+ return markers;
1955
+ };
1956
+ };
1957
+ var SvgElem = function (obj, inherits) {
1958
+ let styleCache = Object.create(null);
1959
+ let childrenCache = null;
1960
+ this.name = obj.nodeName;
1961
+ this.isOuterElement = obj === svg || !obj.parentNode;
1962
+ this.inherits = inherits || (!this.isOuterElement ? createSVGElement(obj.parentNode, null) : null);
1963
+ this.stack = this.inherits ? this.inherits.stack.concat(obj) : [obj];
1964
+ this.style = parseStyleAttr(typeof obj.getAttribute === 'function' && obj.getAttribute('style'));
1965
+ this.css = useCSS ? getComputedStyle(obj) : getStyle(obj);
1966
+ this.allowedChildren = [];
1967
+ this.attr = function (key) {
1968
+ if (typeof obj.getAttribute === 'function') {
1969
+ return obj.getAttribute(key);
1970
+ }
1971
+ };
1972
+ this.resolveUrl = function (value) {
1973
+ let temp = (value || '').match(/^\s*(?:url\("(.*)#(.*)"\)|url\('(.*)#(.*)'\)|url\((.*)#(.*)\)|(.*)#(.*))\s*$/) || [];
1974
+ let file = temp[1] || temp[3] || temp[5] || temp[7],
1975
+ id = temp[2] || temp[4] || temp[6] || temp[8];
1976
+ if (id) {
1977
+ if (!file) {
1978
+ let svgObj = svg.getElementById(id);
1979
+ if (svgObj) {
1980
+ if (this.stack.indexOf(svgObj) === -1) {
1981
+ return svgObj;
1982
+ } else {
1983
+ warningCallback('SVGtoPDF: loop of circular references for id "' + id + '"');
1984
+ return;
1985
+ }
1986
+ }
1987
+ }
1988
+ if (documentCallback) {
1989
+ let svgs = documentCache[file];
1990
+ if (!svgs) {
1991
+ svgs = documentCallback(file);
1992
+ if (!isArrayLike(svgs)) {
1993
+ svgs = [svgs];
1994
+ }
1995
+ for (let i = 0; i < svgs.length; i++) {
1996
+ if (typeof svgs[i] === 'string') {
1997
+ svgs[i] = parseXml(svgs[i]);
1998
+ }
1999
+ }
2000
+ documentCache[file] = svgs;
2001
+ }
2002
+ for (let i = 0; i < svgs.length; i++) {
2003
+ let svgObj = svgs[i].getElementById(id);
2004
+ if (svgObj) {
2005
+ if (this.stack.indexOf(svgObj) === -1) {
2006
+ return svgObj;
2007
+ } else {
2008
+ warningCallback('SVGtoPDF: loop of circular references for id "' + file + '#' + id + '"');
2009
+ return;
2010
+ }
2011
+ }
2012
+ }
2013
+ }
2014
+ }
2015
+ };
2016
+ this.computeUnits = function (value, unit, percent, isFontSize) {
2017
+ if (unit === '%') {
2018
+ return parseFloat(value) / 100 * (isFontSize || percent != null ? percent : this.getViewport());
2019
+ } else if (unit === 'ex' || unit === 'em') {
2020
+ return value * {
2021
+ 'em': 1,
2022
+ 'ex': 0.5
2023
+ }[unit] * (isFontSize ? percent : this.get('font-size'));
2024
+ } else {
2025
+ return value * {
2026
+ '': 1,
2027
+ 'px': 1,
2028
+ 'pt': 96 / 72,
2029
+ 'cm': 96 / 2.54,
2030
+ 'mm': 96 / 25.4,
2031
+ 'in': 96,
2032
+ 'pc': 96 / 6
2033
+ }[unit];
2034
+ }
2035
+ };
2036
+ this.computeLength = function (value, percent, initial, isFontSize) {
2037
+ let parser = new StringParser((value || '').trim()),
2038
+ temp1,
2039
+ temp2;
2040
+ if (typeof (temp1 = parser.matchNumber()) === 'string' && typeof (temp2 = parser.matchLengthUnit()) === 'string' && !parser.matchAll()) {
2041
+ return this.computeUnits(temp1, temp2, percent, isFontSize);
2042
+ }
2043
+ return initial;
2044
+ };
2045
+ this.computeLengthList = function (value, percent, strict) {
2046
+ let parser = new StringParser((value || '').trim()),
2047
+ result = [],
2048
+ temp1,
2049
+ temp2;
2050
+ while (typeof (temp1 = parser.matchNumber()) === 'string' && typeof (temp2 = parser.matchLengthUnit()) === 'string') {
2051
+ result.push(this.computeUnits(temp1, temp2, percent));
2052
+ parser.matchSeparator();
2053
+ }
2054
+ if (strict && parser.matchAll()) {
2055
+ return;
2056
+ }
2057
+ return result;
2058
+ };
2059
+ this.getLength = function (key, percent, initial) {
2060
+ return this.computeLength(this.attr(key), percent, initial);
2061
+ };
2062
+ this.getLengthList = function (key, percent) {
2063
+ return this.computeLengthList(this.attr(key), percent);
2064
+ };
2065
+ this.getUrl = function (key) {
2066
+ return this.resolveUrl(this.attr(key));
2067
+ };
2068
+ this.getNumberList = function (key) {
2069
+ let parser = new StringParser((this.attr(key) || '').trim()),
2070
+ result = [],
2071
+ temp;
2072
+ while (temp = parser.matchNumber()) {
2073
+ result.push(Number(temp));
2074
+ parser.matchSeparator();
2075
+ }
2076
+ result.error = parser.matchAll();
2077
+ return result;
2078
+ };
2079
+ this.getViewbox = function (key, initial) {
2080
+ let viewBox = this.getNumberList(key);
2081
+ if (viewBox.length === 4 && viewBox[2] >= 0 && viewBox[3] >= 0) {
2082
+ return viewBox;
2083
+ }
2084
+ return initial;
2085
+ };
2086
+ this.getPercent = function (key, initial) {
2087
+ let value = this.attr(key);
2088
+ let parser = new StringParser((value || '').trim()),
2089
+ temp1,
2090
+ temp2;
2091
+ let number = parser.matchNumber();
2092
+ if (!number) {
2093
+ return initial;
2094
+ }
2095
+ if (parser.match('%')) {
2096
+ number *= 0.01;
2097
+ }
2098
+ if (parser.matchAll()) {
2099
+ return initial;
2100
+ }
2101
+ return Math.max(0, Math.min(1, number));
2102
+ };
2103
+ this.chooseValue = function (args) {
2104
+ for (let i = 0; i < arguments.length; i++) {
2105
+ if (arguments[i] != null && arguments[i] === arguments[i]) {
2106
+ return arguments[i];
2107
+ }
2108
+ }
2109
+ return arguments[arguments.length - 1];
2110
+ };
2111
+ this.get = function (key) {
2112
+ if (styleCache[key] !== undefined) {
2113
+ return styleCache[key];
2114
+ }
2115
+ let keyInfo = Properties[key] || {},
2116
+ value,
2117
+ result;
2118
+ for (let i = 0; i < 3; i++) {
2119
+ switch (i) {
2120
+ case 0:
2121
+ if (key !== 'transform') {
2122
+ // the CSS transform behaves strangely
2123
+ value = this.css[keyInfo.css || key];
2124
+ }
2125
+ break;
2126
+ case 1:
2127
+ value = this.style[key];
2128
+ break;
2129
+ case 2:
2130
+ value = this.attr(key);
2131
+ break;
2132
+ }
2133
+ if (value === 'inherit') {
2134
+ result = this.inherits ? this.inherits.get(key) : keyInfo.initial;
2135
+ if (result != null) {
2136
+ return styleCache[key] = result;
2137
+ }
2138
+ }
2139
+ if (keyInfo.values != null) {
2140
+ result = keyInfo.values[value];
2141
+ if (result != null) {
2142
+ return styleCache[key] = result;
2143
+ }
2144
+ }
2145
+ if (value != null) {
2146
+ let parsed;
2147
+ switch (key) {
2148
+ case 'font-size':
2149
+ result = this.computeLength(value, this.inherits ? this.inherits.get(key) : keyInfo.initial, undefined, true);
2150
+ break;
2151
+ case 'baseline-shift':
2152
+ result = this.computeLength(value, this.get('font-size'));
2153
+ break;
2154
+ case 'font-family':
2155
+ result = value || undefined;
2156
+ break;
2157
+ case 'opacity':
2158
+ case 'stroke-opacity':
2159
+ case 'fill-opacity':
2160
+ case 'stop-opacity':
2161
+ parsed = parseFloat(value);
2162
+ if (!isNaN(parsed)) {
2163
+ result = Math.max(0, Math.min(1, parsed));
2164
+ }
2165
+ break;
2166
+ case 'transform':
2167
+ result = parseTranform(value);
2168
+ break;
2169
+ case 'stroke-dasharray':
2170
+ if (value === 'none') {
2171
+ result = [];
2172
+ } else if (parsed = this.computeLengthList(value, this.getViewport(), true)) {
2173
+ let sum = 0,
2174
+ error = false;
2175
+ for (let j = 0; j < parsed.length; j++) {
2176
+ if (parsed[j] < 0) {
2177
+ error = true;
2178
+ }
2179
+ sum += parsed[j];
2180
+ }
2181
+ if (!error) {
2182
+ if (parsed.length % 2 === 1) {
2183
+ parsed = parsed.concat(parsed);
2184
+ }
2185
+ result = sum === 0 ? [] : parsed;
2186
+ }
2187
+ }
2188
+ break;
2189
+ case 'color':
2190
+ if (value === 'none' || value === 'transparent') {
2191
+ result = 'none';
2192
+ } else {
2193
+ result = parseColor(value);
2194
+ }
2195
+ break;
2196
+ case 'fill':
2197
+ case 'stroke':
2198
+ if (value === 'none' || value === 'transparent') {
2199
+ result = 'none';
2200
+ } else if (value === 'currentColor') {
2201
+ result = this.get('color');
2202
+ } else if (parsed = parseColor(value)) {
2203
+ return parsed;
2204
+ } else if (parsed = (value || '').split(' ')) {
2205
+ let object = this.resolveUrl(parsed[0]),
2206
+ fallbackColor = parseColor(parsed[1]);
2207
+ if (object == null) {
2208
+ result = fallbackColor;
2209
+ } else if (object.nodeName === 'linearGradient' || object.nodeName === 'radialGradient') {
2210
+ result = new SvgElemGradient(object, null, fallbackColor);
2211
+ } else if (object.nodeName === 'pattern') {
2212
+ result = new SvgElemPattern(object, null, fallbackColor);
2213
+ } else {
2214
+ result = fallbackColor;
2215
+ }
2216
+ }
2217
+ break;
2218
+ case 'stop-color':
2219
+ if (value === 'none' || value === 'transparent') {
2220
+ result = 'none';
2221
+ } else if (value === 'currentColor') {
2222
+ result = this.get('color');
2223
+ } else {
2224
+ result = parseColor(value);
2225
+ }
2226
+ break;
2227
+ case 'marker-start':
2228
+ case 'marker-mid':
2229
+ case 'marker-end':
2230
+ case 'clip-path':
2231
+ case 'mask':
2232
+ if (value === 'none') {
2233
+ result = 'none';
2234
+ } else {
2235
+ result = this.resolveUrl(value);
2236
+ }
2237
+ break;
2238
+ case 'stroke-width':
2239
+ parsed = this.computeLength(value, this.getViewport());
2240
+ if (parsed != null && parsed >= 0) {
2241
+ result = parsed;
2242
+ }
2243
+ break;
2244
+ case 'stroke-miterlimit':
2245
+ parsed = parseFloat(value);
2246
+ if (parsed != null && parsed >= 1) {
2247
+ result = parsed;
2248
+ }
2249
+ break;
2250
+ case 'word-spacing':
2251
+ case 'letter-spacing':
2252
+ result = this.computeLength(value, this.getViewport());
2253
+ break;
2254
+ case 'stroke-dashoffset':
2255
+ result = this.computeLength(value, this.getViewport());
2256
+ if (result != null) {
2257
+ if (result < 0) {
2258
+ // fix for crbug.com/660850
2259
+ let dasharray = this.get('stroke-dasharray');
2260
+ for (let j = 0; j < dasharray.length; j++) {
2261
+ result += dasharray[j];
2262
+ }
2263
+ }
2264
+ }
2265
+ break;
2266
+ }
2267
+ if (result != null) {
2268
+ return styleCache[key] = result;
2269
+ }
2270
+ }
2271
+ }
2272
+ return styleCache[key] = keyInfo.inherit && this.inherits ? this.inherits.get(key) : keyInfo.initial;
2273
+ };
2274
+ this.getChildren = function () {
2275
+ if (childrenCache != null) {
2276
+ return childrenCache;
2277
+ }
2278
+ let children = [];
2279
+ for (let i = 0; i < obj.childNodes.length; i++) {
2280
+ let child = obj.childNodes[i];
2281
+ if (!child.error && this.allowedChildren.indexOf(child.nodeName) !== -1) {
2282
+ children.push(createSVGElement(child, this));
2283
+ }
2284
+ }
2285
+ return childrenCache = children;
2286
+ };
2287
+ this.getParentVWidth = function () {
2288
+ return this.inherits ? this.inherits.getVWidth() : viewportWidth;
2289
+ };
2290
+ this.getParentVHeight = function () {
2291
+ return this.inherits ? this.inherits.getVHeight() : viewportHeight;
2292
+ };
2293
+ this.getParentViewport = function () {
2294
+ return Math.sqrt(0.5 * this.getParentVWidth() * this.getParentVWidth() + 0.5 * this.getParentVHeight() * this.getParentVHeight());
2295
+ };
2296
+ this.getVWidth = function () {
2297
+ return this.getParentVWidth();
2298
+ };
2299
+ this.getVHeight = function () {
2300
+ return this.getParentVHeight();
2301
+ };
2302
+ this.getViewport = function () {
2303
+ return Math.sqrt(0.5 * this.getVWidth() * this.getVWidth() + 0.5 * this.getVHeight() * this.getVHeight());
2304
+ };
2305
+ this.getBoundingBox = function () {
2306
+ let shape = this.getBoundingShape();
2307
+ return shape.getBoundingBox();
2308
+ };
2309
+ };
2310
+ var SvgElemStylable = function (obj, inherits) {
2311
+ SvgElem.call(this, obj, inherits);
2312
+ this.transform = function () {
2313
+ doc.transform.apply(doc, this.getTransformation());
2314
+ };
2315
+ this.clip = function () {
2316
+ if (this.get('clip-path') !== 'none') {
2317
+ let clipPath = new SvgElemClipPath(this.get('clip-path'), null);
2318
+ clipPath.useMask(this.getBoundingBox());
2319
+ return true;
2320
+ }
2321
+ };
2322
+ this.mask = function () {
2323
+ if (this.get('mask') !== 'none') {
2324
+ let mask = new SvgElemMask(this.get('mask'), null);
2325
+ mask.useMask(this.getBoundingBox());
2326
+ return true;
2327
+ }
2328
+ };
2329
+ this.getFill = function (isClip, isMask) {
2330
+ let opacity = this.get('opacity'),
2331
+ fill = this.get('fill'),
2332
+ fillOpacity = this.get('fill-opacity');
2333
+ if (isClip) {
2334
+ return DefaultColors.white;
2335
+ }
2336
+ if (fill !== 'none' && opacity && fillOpacity) {
2337
+ if (fill instanceof SvgElemGradient || fill instanceof SvgElemPattern) {
2338
+ return fill.getPaint(this.getBoundingBox(), fillOpacity * opacity, isClip, isMask);
2339
+ }
2340
+ return opacityToColor(fill, fillOpacity * opacity, isMask);
2341
+ }
2342
+ };
2343
+ this.getStroke = function (isClip, isMask) {
2344
+ let opacity = this.get('opacity'),
2345
+ stroke = this.get('stroke'),
2346
+ strokeOpacity = this.get('stroke-opacity');
2347
+ if (isClip || isEqual(this.get('stroke-width'), 0)) {
2348
+ return;
2349
+ }
2350
+ if (stroke !== 'none' && opacity && strokeOpacity) {
2351
+ if (stroke instanceof SvgElemGradient || stroke instanceof SvgElemPattern) {
2352
+ return stroke.getPaint(this.getBoundingBox(), strokeOpacity * opacity, isClip, isMask);
2353
+ }
2354
+ return opacityToColor(stroke, strokeOpacity * opacity, isMask);
2355
+ }
2356
+ };
2357
+ };
2358
+ var SvgElemHasChildren = function (obj, inherits) {
2359
+ SvgElemStylable.call(this, obj, inherits);
2360
+ this.allowedChildren = ['use', 'g', 'a', 'svg', 'image', 'rect', 'circle', 'ellipse', 'line', 'polyline', 'polygon', 'path', 'text'];
2361
+ this.getBoundingShape = function () {
2362
+ let shape = new SvgShape(),
2363
+ children = this.getChildren();
2364
+ for (let i = 0; i < children.length; i++) {
2365
+ if (children[i].get('display') !== 'none') {
2366
+ if (typeof children[i].getBoundingShape === 'function') {
2367
+ let childShape = children[i].getBoundingShape().clone();
2368
+ if (typeof children[i].getTransformation === 'function') {
2369
+ childShape.transform(children[i].getTransformation());
2370
+ }
2371
+ shape.mergeShape(childShape);
2372
+ }
2373
+ }
2374
+ }
2375
+ return shape;
2376
+ };
2377
+ this.drawChildren = function (isClip, isMask) {
2378
+ let children = this.getChildren();
2379
+ for (let i = 0; i < children.length; i++) {
2380
+ if (children[i].get('display') !== 'none') {
2381
+ if (typeof children[i].drawInDocument === 'function') {
2382
+ children[i].drawInDocument(isClip, isMask);
2383
+ }
2384
+ }
2385
+ }
2386
+ };
2387
+ };
2388
+ var SvgElemContainer = function (obj, inherits) {
2389
+ SvgElemHasChildren.call(this, obj, inherits);
2390
+ this.drawContent = function (isClip, isMask) {
2391
+ this.transform();
2392
+ let clipped = this.clip(),
2393
+ masked = this.mask(),
2394
+ group;
2395
+ if ((this.get('opacity') < 1 || clipped || masked) && !isClip) {
2396
+ group = docBeginGroup(getPageBBox());
2397
+ }
2398
+ this.drawChildren(isClip, isMask);
2399
+ if (group) {
2400
+ docEndGroup(group);
2401
+ doc.fillOpacity(this.get('opacity'));
2402
+ docInsertGroup(group);
2403
+ }
2404
+ };
2405
+ };
2406
+ var SvgElemUse = function (obj, inherits) {
2407
+ SvgElemContainer.call(this, obj, inherits);
2408
+ let x = this.getLength('x', this.getVWidth(), 0),
2409
+ y = this.getLength('y', this.getVHeight(), 0),
2410
+ child = this.getUrl('href') || this.getUrl('xlink:href');
2411
+ if (child) {
2412
+ child = createSVGElement(child, this);
2413
+ }
2414
+ this.getChildren = function () {
2415
+ return child ? [child] : [];
2416
+ };
2417
+ this.drawInDocument = function (isClip, isMask) {
2418
+ doc.save();
2419
+ this.drawContent(isClip, isMask);
2420
+ doc.restore();
2421
+ };
2422
+ this.getTransformation = function () {
2423
+ return multiplyMatrix(this.get('transform'), [1, 0, 0, 1, x, y]);
2424
+ };
2425
+ };
2426
+ var SvgElemSymbol = function (obj, inherits) {
2427
+ SvgElemContainer.call(this, obj, inherits);
2428
+ let width = this.getLength('width', this.getParentVWidth(), this.getParentVWidth()),
2429
+ height = this.getLength('height', this.getParentVHeight(), this.getParentVHeight());
2430
+ if (inherits instanceof SvgElemUse) {
2431
+ width = inherits.getLength('width', inherits.getParentVWidth(), width);
2432
+ height = inherits.getLength('height', inherits.getParentVHeight(), height);
2433
+ }
2434
+ let aspectRatio = (this.attr('preserveAspectRatio') || '').trim(),
2435
+ viewBox = this.getViewbox('viewBox', [0, 0, width, height]);
2436
+ this.getVWidth = function () {
2437
+ return viewBox[2];
2438
+ };
2439
+ this.getVHeight = function () {
2440
+ return viewBox[3];
2441
+ };
2442
+ this.drawInDocument = function (isClip, isMask) {
2443
+ doc.save();
2444
+ this.drawContent(isClip, isMask);
2445
+ doc.restore();
2446
+ };
2447
+ this.getTransformation = function () {
2448
+ return multiplyMatrix(parseAspectRatio(aspectRatio, width, height, viewBox[2], viewBox[3]), [1, 0, 0, 1, -viewBox[0], -viewBox[1]]);
2449
+ };
2450
+ };
2451
+ var SvgElemGroup = function (obj, inherits) {
2452
+ SvgElemContainer.call(this, obj, inherits);
2453
+ this.drawInDocument = function (isClip, isMask) {
2454
+ doc.save();
2455
+ if (this.link && !isClip && !isMask) {
2456
+ this.addLink();
2457
+ }
2458
+ this.drawContent(isClip, isMask);
2459
+ doc.restore();
2460
+ };
2461
+ this.getTransformation = function () {
2462
+ return this.get('transform');
2463
+ };
2464
+ };
2465
+ var SvgElemLink = function (obj, inherits) {
2466
+ if (inherits && inherits.isText) {
2467
+ SvgElemTspan.call(this, obj, inherits);
2468
+ this.allowedChildren = ['textPath', 'tspan', '#text', '#cdata-section', 'a'];
2469
+ } else {
2470
+ SvgElemGroup.call(this, obj, inherits);
2471
+ }
2472
+ this.link = this.attr('href') || this.attr('xlink:href');
2473
+ this.addLink = function () {
2474
+ if (this.link.match(/^(?:[a-z][a-z0-9+.-]*:|\/\/)?/i) && this.getChildren().length) {
2475
+ let bbox = this.getBoundingShape().transform(getGlobalMatrix()).getBoundingBox();
2476
+ docInsertLink(bbox[0], bbox[1], bbox[2], bbox[3], this.link);
2477
+ }
2478
+ };
2479
+ };
2480
+ var SvgElemSvg = function (obj, inherits) {
2481
+ SvgElemContainer.call(this, obj, inherits);
2482
+ let width = this.getLength('width', this.getParentVWidth(), this.getParentVWidth()),
2483
+ height = this.getLength('height', this.getParentVHeight(), this.getParentVHeight()),
2484
+ x = this.getLength('x', this.getParentVWidth(), 0),
2485
+ y = this.getLength('y', this.getParentVHeight(), 0);
2486
+ if (inherits instanceof SvgElemUse) {
2487
+ width = inherits.getLength('width', inherits.getParentVWidth(), width);
2488
+ height = inherits.getLength('height', inherits.getParentVHeight(), height);
2489
+ }
2490
+ let aspectRatio = this.attr('preserveAspectRatio'),
2491
+ viewBox = this.getViewbox('viewBox', [0, 0, width, height]);
2492
+ if (this.isOuterElement && preserveAspectRatio) {
2493
+ x = y = 0;
2494
+ width = viewportWidth;
2495
+ height = viewportHeight;
2496
+ aspectRatio = preserveAspectRatio;
2497
+ }
2498
+ this.getVWidth = function () {
2499
+ return viewBox[2];
2500
+ };
2501
+ this.getVHeight = function () {
2502
+ return viewBox[3];
2503
+ };
2504
+ this.drawInDocument = function (isClip, isMask) {
2505
+ doc.save();
2506
+ if (this.get('overflow') === 'hidden') {
2507
+ new SvgShape().M(x, y).L(x + width, y).L(x + width, y + height).L(x, y + height).Z().transform(this.get('transform')).insertInDocument();
2508
+ doc.clip();
2509
+ }
2510
+ this.drawContent(isClip, isMask);
2511
+ doc.restore();
2512
+ };
2513
+ this.getTransformation = function () {
2514
+ return multiplyMatrix(this.get('transform'), [1, 0, 0, 1, x, y], parseAspectRatio(aspectRatio, width, height, viewBox[2], viewBox[3]), [1, 0, 0, 1, -viewBox[0], -viewBox[1]]);
2515
+ };
2516
+ };
2517
+ var SVGElemImage = function (obj, inherits) {
2518
+ SvgElemStylable.call(this, obj, inherits);
2519
+ let link = imageCallback(this.attr('href') || this.attr('xlink:href') || ''),
2520
+ x = this.getLength('x', this.getVWidth(), 0),
2521
+ y = this.getLength('y', this.getVHeight(), 0),
2522
+ width = this.getLength('width', this.getVWidth(), 'auto'),
2523
+ height = this.getLength('height', this.getVHeight(), 'auto'),
2524
+ image;
2525
+ try {
2526
+ image = doc.openImage(link);
2527
+ } catch (e) {
2528
+ warningCallback('SVGElemImage: failed to open image "' + link + '" in PDFKit');
2529
+ }
2530
+ if (image) {
2531
+ if (width === 'auto' && height !== 'auto') {
2532
+ width = height * image.width / image.height;
2533
+ } else if (height === 'auto' && width !== 'auto') {
2534
+ height = width * image.height / image.width;
2535
+ } else if (width === 'auto' && height === 'auto') {
2536
+ width = image.width;
2537
+ height = image.height;
2538
+ }
2539
+ }
2540
+ if (width === 'auto' || width < 0) {
2541
+ width = 0;
2542
+ }
2543
+ if (height === 'auto' || height < 0) {
2544
+ height = 0;
2545
+ }
2546
+ this.getTransformation = function () {
2547
+ return this.get('transform');
2548
+ };
2549
+ this.getBoundingShape = function () {
2550
+ return new SvgShape().M(x, y).L(x + width, y).M(x + width, y + height).L(x, y + height);
2551
+ };
2552
+ this.drawInDocument = function (isClip, isMask) {
2553
+ if (this.get('visibility') === 'hidden' || !image) {
2554
+ return;
2555
+ }
2556
+ doc.save();
2557
+ this.transform();
2558
+ if (this.get('overflow') === 'hidden') {
2559
+ doc.rect(x, y, width, height).clip();
2560
+ }
2561
+ this.clip();
2562
+ this.mask();
2563
+ doc.translate(x, y);
2564
+ doc.transform.apply(doc, parseAspectRatio(this.attr('preserveAspectRatio'), width, height, image ? image.width : width, image ? image.height : height));
2565
+ if (!isClip) {
2566
+ doc.fillOpacity(this.get('opacity'));
2567
+ doc.image(image, 0, 0);
2568
+ } else {
2569
+ doc.rect(0, 0, image.width, image.height);
2570
+ docFillColor(DefaultColors.white).fill();
2571
+ }
2572
+ doc.restore();
2573
+ };
2574
+ };
2575
+ var SvgElemPattern = function (obj, inherits, fallback) {
2576
+ SvgElemHasChildren.call(this, obj, inherits);
2577
+ this.ref = function () {
2578
+ let ref = this.getUrl('href') || this.getUrl('xlink:href');
2579
+ if (ref && ref.nodeName === obj.nodeName) {
2580
+ return new SvgElemPattern(ref, inherits, fallback);
2581
+ }
2582
+ }.call(this);
2583
+ let _attr = this.attr;
2584
+ this.attr = function (key) {
2585
+ let attr = _attr.call(this, key);
2586
+ if (attr != null || key === 'href' || key === 'xlink:href') {
2587
+ return attr;
2588
+ }
2589
+ return this.ref ? this.ref.attr(key) : null;
2590
+ };
2591
+ let _getChildren = this.getChildren;
2592
+ this.getChildren = function () {
2593
+ let children = _getChildren.call(this);
2594
+ if (children.length > 0) {
2595
+ return children;
2596
+ }
2597
+ return this.ref ? this.ref.getChildren() : [];
2598
+ };
2599
+ this.getPaint = function (bBox, gOpacity, isClip, isMask) {
2600
+ let bBoxUnitsPattern = this.attr('patternUnits') !== 'userSpaceOnUse',
2601
+ bBoxUnitsContent = this.attr('patternContentUnits') === 'objectBoundingBox',
2602
+ x = this.getLength('x', bBoxUnitsPattern ? 1 : this.getParentVWidth(), 0),
2603
+ y = this.getLength('y', bBoxUnitsPattern ? 1 : this.getParentVHeight(), 0),
2604
+ width = this.getLength('width', bBoxUnitsPattern ? 1 : this.getParentVWidth(), 0),
2605
+ height = this.getLength('height', bBoxUnitsPattern ? 1 : this.getParentVHeight(), 0);
2606
+ if (bBoxUnitsContent && !bBoxUnitsPattern) {
2607
+ // Use the same units for pattern & pattern content
2608
+ x = (x - bBox[0]) / (bBox[2] - bBox[0]) || 0;
2609
+ y = (y - bBox[1]) / (bBox[3] - bBox[1]) || 0;
2610
+ width = width / (bBox[2] - bBox[0]) || 0;
2611
+ height = height / (bBox[3] - bBox[1]) || 0;
2612
+ } else if (!bBoxUnitsContent && bBoxUnitsPattern) {
2613
+ x = bBox[0] + x * (bBox[2] - bBox[0]);
2614
+ y = bBox[1] + y * (bBox[3] - bBox[1]);
2615
+ width = width * (bBox[2] - bBox[0]);
2616
+ height = height * (bBox[3] - bBox[1]);
2617
+ }
2618
+ let viewBox = this.getViewbox('viewBox', [0, 0, width, height]),
2619
+ aspectRatio = (this.attr('preserveAspectRatio') || '').trim(),
2620
+ aspectRatioMatrix = multiplyMatrix(parseAspectRatio(aspectRatio, width, height, viewBox[2], viewBox[3], 0), [1, 0, 0, 1, -viewBox[0], -viewBox[1]]),
2621
+ matrix = parseTranform(this.attr('patternTransform'));
2622
+ if (bBoxUnitsContent) {
2623
+ matrix = multiplyMatrix([bBox[2] - bBox[0], 0, 0, bBox[3] - bBox[1], bBox[0], bBox[1]], matrix);
2624
+ }
2625
+ matrix = multiplyMatrix(matrix, [1, 0, 0, 1, x, y]);
2626
+ if ((matrix = validateMatrix(matrix)) && (aspectRatioMatrix = validateMatrix(aspectRatioMatrix)) && (width = validateNumber(width)) && (height = validateNumber(height))) {
2627
+ let group = docBeginGroup([0, 0, width, height]);
2628
+ doc.transform.apply(doc, aspectRatioMatrix);
2629
+ this.drawChildren(isClip, isMask);
2630
+ docEndGroup(group);
2631
+ return [docCreatePattern(group, width, height, matrix), gOpacity];
2632
+ } else {
2633
+ return fallback ? [fallback[0], fallback[1] * gOpacity] : undefined;
2634
+ }
2635
+ };
2636
+ this.getVWidth = function () {
2637
+ let bBoxUnitsPattern = this.attr('patternUnits') !== 'userSpaceOnUse',
2638
+ width = this.getLength('width', bBoxUnitsPattern ? 1 : this.getParentVWidth(), 0);
2639
+ return this.getViewbox('viewBox', [0, 0, width, 0])[2];
2640
+ };
2641
+ this.getVHeight = function () {
2642
+ let bBoxUnitsPattern = this.attr('patternUnits') !== 'userSpaceOnUse',
2643
+ height = this.getLength('height', bBoxUnitsPattern ? 1 : this.getParentVHeight(), 0);
2644
+ return this.getViewbox('viewBox', [0, 0, 0, height])[3];
2645
+ };
2646
+ };
2647
+ var SvgElemGradient = function (obj, inherits, fallback) {
2648
+ SvgElem.call(this, obj, inherits);
2649
+ this.allowedChildren = ['stop'];
2650
+ this.ref = function () {
2651
+ let ref = this.getUrl('href') || this.getUrl('xlink:href');
2652
+ if (ref && ref.nodeName === obj.nodeName) {
2653
+ return new SvgElemGradient(ref, inherits, fallback);
2654
+ }
2655
+ }.call(this);
2656
+ let _attr = this.attr;
2657
+ this.attr = function (key) {
2658
+ let attr = _attr.call(this, key);
2659
+ if (attr != null || key === 'href' || key === 'xlink:href') {
2660
+ return attr;
2661
+ }
2662
+ return this.ref ? this.ref.attr(key) : null;
2663
+ };
2664
+ let _getChildren = this.getChildren;
2665
+ this.getChildren = function () {
2666
+ let children = _getChildren.call(this);
2667
+ if (children.length > 0) {
2668
+ return children;
2669
+ }
2670
+ return this.ref ? this.ref.getChildren() : [];
2671
+ };
2672
+ this.getPaint = function (bBox, gOpacity, isClip, isMask) {
2673
+ let children = this.getChildren();
2674
+ if (children.length === 0) {
2675
+ return;
2676
+ }
2677
+ if (children.length === 1) {
2678
+ let child = children[0],
2679
+ stopColor = child.get('stop-color');
2680
+ if (stopColor === 'none') {
2681
+ return;
2682
+ }
2683
+ return opacityToColor(stopColor, child.get('stop-opacity') * gOpacity, isMask);
2684
+ }
2685
+ let bBoxUnits = this.attr('gradientUnits') !== 'userSpaceOnUse',
2686
+ matrix = parseTranform(this.attr('gradientTransform')),
2687
+ spread = this.attr('spreadMethod'),
2688
+ grad,
2689
+ x1,
2690
+ x2,
2691
+ y1,
2692
+ y2,
2693
+ r2,
2694
+ nAfter = 0,
2695
+ nBefore = 0,
2696
+ nTotal = 1;
2697
+ if (bBoxUnits) {
2698
+ matrix = multiplyMatrix([bBox[2] - bBox[0], 0, 0, bBox[3] - bBox[1], bBox[0], bBox[1]], matrix);
2699
+ }
2700
+ if (matrix = validateMatrix(matrix)) {
2701
+ if (this.name === 'linearGradient') {
2702
+ x1 = this.getLength('x1', bBoxUnits ? 1 : this.getVWidth(), 0);
2703
+ x2 = this.getLength('x2', bBoxUnits ? 1 : this.getVWidth(), bBoxUnits ? 1 : this.getVWidth());
2704
+ y1 = this.getLength('y1', bBoxUnits ? 1 : this.getVHeight(), 0);
2705
+ y2 = this.getLength('y2', bBoxUnits ? 1 : this.getVHeight(), 0);
2706
+ } else {
2707
+ x2 = this.getLength('cx', bBoxUnits ? 1 : this.getVWidth(), bBoxUnits ? 0.5 : 0.5 * this.getVWidth());
2708
+ y2 = this.getLength('cy', bBoxUnits ? 1 : this.getVHeight(), bBoxUnits ? 0.5 : 0.5 * this.getVHeight());
2709
+ r2 = this.getLength('r', bBoxUnits ? 1 : this.getViewport(), bBoxUnits ? 0.5 : 0.5 * this.getViewport());
2710
+ x1 = this.getLength('fx', bBoxUnits ? 1 : this.getVWidth(), x2);
2711
+ y1 = this.getLength('fy', bBoxUnits ? 1 : this.getVHeight(), y2);
2712
+ if (r2 < 0) {
2713
+ warningCallback('SvgElemGradient: negative r value');
2714
+ }
2715
+ let d = Math.sqrt(Math.pow(x2 - x1, 2) + Math.pow(y2 - y1, 2)),
2716
+ multiplier = 1;
2717
+ if (d > r2) {
2718
+ // according to specification
2719
+ multiplier = r2 / d;
2720
+ x1 = x2 + (x1 - x2) * multiplier;
2721
+ y1 = y2 + (y1 - y2) * multiplier;
2722
+ }
2723
+ r2 = Math.max(r2, d * multiplier * (1 + 1e-6)); // fix for edge-case gradients see issue #84
2724
+ }
2725
+ if (spread === 'reflect' || spread === 'repeat') {
2726
+ let inv = inverseMatrix(matrix),
2727
+ corner1 = transformPoint([bBox[0], bBox[1]], inv),
2728
+ corner2 = transformPoint([bBox[2], bBox[1]], inv),
2729
+ corner3 = transformPoint([bBox[2], bBox[3]], inv),
2730
+ corner4 = transformPoint([bBox[0], bBox[3]], inv);
2731
+ if (this.name === 'linearGradient') {
2732
+ // See file 'gradient-repeat-maths.png'
2733
+ nAfter = Math.max((corner1[0] - x2) * (x2 - x1) + (corner1[1] - y2) * (y2 - y1), (corner2[0] - x2) * (x2 - x1) + (corner2[1] - y2) * (y2 - y1), (corner3[0] - x2) * (x2 - x1) + (corner3[1] - y2) * (y2 - y1), (corner4[0] - x2) * (x2 - x1) + (corner4[1] - y2) * (y2 - y1)) / (Math.pow(x2 - x1, 2) + Math.pow(y2 - y1, 2));
2734
+ nBefore = Math.max((corner1[0] - x1) * (x1 - x2) + (corner1[1] - y1) * (y1 - y2), (corner2[0] - x1) * (x1 - x2) + (corner2[1] - y1) * (y1 - y2), (corner3[0] - x1) * (x1 - x2) + (corner3[1] - y1) * (y1 - y2), (corner4[0] - x1) * (x1 - x2) + (corner4[1] - y1) * (y1 - y2)) / (Math.pow(x2 - x1, 2) + Math.pow(y2 - y1, 2));
2735
+ } else {
2736
+ nAfter = Math.sqrt(Math.max(Math.pow(corner1[0] - x2, 2) + Math.pow(corner1[1] - y2, 2), Math.pow(corner2[0] - x2, 2) + Math.pow(corner2[1] - y2, 2), Math.pow(corner3[0] - x2, 2) + Math.pow(corner3[1] - y2, 2), Math.pow(corner4[0] - x2, 2) + Math.pow(corner4[1] - y2, 2))) / r2 - 1;
2737
+ }
2738
+ nAfter = Math.ceil(nAfter + 0.5); // Add a little more because the stroke can extend outside of the bounding box
2739
+ nBefore = Math.ceil(nBefore + 0.5);
2740
+ nTotal = nBefore + 1 + nAfter; // How many times the gradient needs to be repeated to fill the object bounding box
2741
+ }
2742
+ if (this.name === 'linearGradient') {
2743
+ grad = doc.linearGradient(x1 - nBefore * (x2 - x1), y1 - nBefore * (y2 - y1), x2 + nAfter * (x2 - x1), y2 + nAfter * (y2 - y1));
2744
+ } else {
2745
+ grad = doc.radialGradient(x1, y1, 0, x2, y2, r2 + nAfter * r2);
2746
+ }
2747
+ for (let n = 0; n < nTotal; n++) {
2748
+ let offset = 0,
2749
+ inOrder = spread !== 'reflect' || (n - nBefore) % 2 === 0;
2750
+ for (let i = 0; i < children.length; i++) {
2751
+ let child = children[inOrder ? i : children.length - 1 - i],
2752
+ stopColor = child.get('stop-color');
2753
+ if (stopColor === 'none') {
2754
+ stopColor = DefaultColors.transparent;
2755
+ }
2756
+ stopColor = opacityToColor(stopColor, child.get('stop-opacity') * gOpacity, isMask);
2757
+ offset = Math.max(offset, inOrder ? child.getPercent('offset', 0) : 1 - child.getPercent('offset', 0));
2758
+ if (i === 0 && stopColor[0].length === 4) {
2759
+ grad._colorSpace = 'DeviceCMYK';
2760
+ } // Fix until PR #763 is merged into PDFKit
2761
+ if (i === 0 && offset > 0) {
2762
+ grad.stop((n + 0) / nTotal, stopColor[0], stopColor[1]);
2763
+ }
2764
+ grad.stop((n + offset) / (nAfter + nBefore + 1), stopColor[0], stopColor[1]);
2765
+ if (i === children.length - 1 && offset < 1) {
2766
+ grad.stop((n + 1) / nTotal, stopColor[0], stopColor[1]);
2767
+ }
2768
+ }
2769
+ }
2770
+ grad.setTransform.apply(grad, matrix);
2771
+ return [grad, 1];
2772
+ } else {
2773
+ return fallback ? [fallback[0], fallback[1] * gOpacity] : undefined;
2774
+ }
2775
+ };
2776
+ };
2777
+ var SvgElemBasicShape = function (obj, inherits) {
2778
+ SvgElemStylable.call(this, obj, inherits);
2779
+ this.dashScale = 1;
2780
+ this.getBoundingShape = function () {
2781
+ return this.shape;
2782
+ };
2783
+ this.getTransformation = function () {
2784
+ return this.get('transform');
2785
+ };
2786
+ this.drawInDocument = function (isClip, isMask) {
2787
+ if (this.get('visibility') === 'hidden' || !this.shape) {
2788
+ return;
2789
+ }
2790
+ doc.save();
2791
+ this.transform();
2792
+ this.clip();
2793
+ if (!isClip) {
2794
+ let masked = this.mask(),
2795
+ group;
2796
+ if (masked) {
2797
+ group = docBeginGroup(getPageBBox());
2798
+ }
2799
+ let subPaths = this.shape.getSubPaths(),
2800
+ fill = this.getFill(isClip, isMask),
2801
+ stroke = this.getStroke(isClip, isMask),
2802
+ lineWidth = this.get('stroke-width'),
2803
+ lineCap = this.get('stroke-linecap');
2804
+ if (fill || stroke) {
2805
+ if (fill) {
2806
+ docFillColor(fill);
2807
+ }
2808
+ if (stroke) {
2809
+ for (let j = 0; j < subPaths.length; j++) {
2810
+ if (isEqual(subPaths[j].totalLength, 0)) {
2811
+ if ((lineCap === 'square' || lineCap === 'round') && lineWidth > 0) {
2812
+ if (subPaths[j].startPoint && subPaths[j].startPoint.length > 1) {
2813
+ let x = subPaths[j].startPoint[0],
2814
+ y = subPaths[j].startPoint[1];
2815
+ docFillColor(stroke);
2816
+ if (lineCap === 'square') {
2817
+ doc.rect(x - 0.5 * lineWidth, y - 0.5 * lineWidth, lineWidth, lineWidth);
2818
+ } else if (lineCap === 'round') {
2819
+ doc.circle(x, y, 0.5 * lineWidth);
2820
+ }
2821
+ doc.fill();
2822
+ }
2823
+ }
2824
+ }
2825
+ }
2826
+ let dashArray = this.get('stroke-dasharray'),
2827
+ dashOffset = this.get('stroke-dashoffset');
2828
+ if (isNotEqual(this.dashScale, 1)) {
2829
+ for (let j = 0; j < dashArray.length; j++) {
2830
+ dashArray[j] *= this.dashScale;
2831
+ }
2832
+ dashOffset *= this.dashScale;
2833
+ }
2834
+ docStrokeColor(stroke);
2835
+ doc.lineWidth(lineWidth).miterLimit(this.get('stroke-miterlimit')).lineJoin(this.get('stroke-linejoin')).lineCap(lineCap).dash(dashArray, {
2836
+ phase: dashOffset
2837
+ });
2838
+ }
2839
+ for (let j = 0; j < subPaths.length; j++) {
2840
+ if (subPaths[j].totalLength > 0) {
2841
+ subPaths[j].insertInDocument();
2842
+ }
2843
+ }
2844
+ if (fill && stroke) {
2845
+ doc.fillAndStroke(this.get('fill-rule'));
2846
+ } else if (fill) {
2847
+ doc.fill(this.get('fill-rule'));
2848
+ } else if (stroke) {
2849
+ doc.stroke();
2850
+ }
2851
+ }
2852
+ let markerStart = this.get('marker-start'),
2853
+ markerMid = this.get('marker-mid'),
2854
+ markerEnd = this.get('marker-end');
2855
+ if (markerStart !== 'none' || markerMid !== 'none' || markerEnd !== 'none') {
2856
+ let markersPos = this.shape.getMarkers();
2857
+ if (markerStart !== 'none') {
2858
+ let marker = new SvgElemMarker(markerStart, null);
2859
+ marker.drawMarker(false, isMask, markersPos[0], lineWidth);
2860
+ }
2861
+ if (markerMid !== 'none') {
2862
+ for (let i = 1; i < markersPos.length - 1; i++) {
2863
+ let marker = new SvgElemMarker(markerMid, null);
2864
+ marker.drawMarker(false, isMask, markersPos[i], lineWidth);
2865
+ }
2866
+ }
2867
+ if (markerEnd !== 'none') {
2868
+ let marker = new SvgElemMarker(markerEnd, null);
2869
+ marker.drawMarker(false, isMask, markersPos[markersPos.length - 1], lineWidth);
2870
+ }
2871
+ }
2872
+ if (group) {
2873
+ docEndGroup(group);
2874
+ docInsertGroup(group);
2875
+ }
2876
+ } else {
2877
+ this.shape.insertInDocument();
2878
+ docFillColor(DefaultColors.white);
2879
+ doc.fill(this.get('clip-rule'));
2880
+ }
2881
+ doc.restore();
2882
+ };
2883
+ };
2884
+ var SvgElemRect = function (obj, inherits) {
2885
+ SvgElemBasicShape.call(this, obj, inherits);
2886
+ let x = this.getLength('x', this.getVWidth(), 0),
2887
+ y = this.getLength('y', this.getVHeight(), 0),
2888
+ w = this.getLength('width', this.getVWidth(), 0),
2889
+ h = this.getLength('height', this.getVHeight(), 0),
2890
+ rx = this.getLength('rx', this.getVWidth()),
2891
+ ry = this.getLength('ry', this.getVHeight());
2892
+ if (rx === undefined && ry === undefined) {
2893
+ rx = ry = 0;
2894
+ } else if (rx === undefined && ry !== undefined) {
2895
+ rx = ry;
2896
+ } else if (rx !== undefined && ry === undefined) {
2897
+ ry = rx;
2898
+ }
2899
+ if (w > 0 && h > 0) {
2900
+ if (rx && ry) {
2901
+ rx = Math.min(rx, 0.5 * w);
2902
+ ry = Math.min(ry, 0.5 * h);
2903
+ this.shape = new SvgShape().M(x + rx, y).L(x + w - rx, y).A(rx, ry, 0, 0, 1, x + w, y + ry).L(x + w, y + h - ry).A(rx, ry, 0, 0, 1, x + w - rx, y + h).L(x + rx, y + h).A(rx, ry, 0, 0, 1, x, y + h - ry).L(x, y + ry).A(rx, ry, 0, 0, 1, x + rx, y).Z();
2904
+ } else {
2905
+ this.shape = new SvgShape().M(x, y).L(x + w, y).L(x + w, y + h).L(x, y + h).Z();
2906
+ }
2907
+ } else {
2908
+ this.shape = new SvgShape();
2909
+ }
2910
+ };
2911
+ var SvgElemCircle = function (obj, inherits) {
2912
+ SvgElemBasicShape.call(this, obj, inherits);
2913
+ let cx = this.getLength('cx', this.getVWidth(), 0),
2914
+ cy = this.getLength('cy', this.getVHeight(), 0),
2915
+ r = this.getLength('r', this.getViewport(), 0);
2916
+ if (r > 0) {
2917
+ this.shape = new SvgShape().M(cx + r, cy).A(r, r, 0, 0, 1, cx - r, cy).A(r, r, 0, 0, 1, cx + r, cy).Z();
2918
+ } else {
2919
+ this.shape = new SvgShape();
2920
+ }
2921
+ };
2922
+ var SvgElemEllipse = function (obj, inherits) {
2923
+ SvgElemBasicShape.call(this, obj, inherits);
2924
+ let cx = this.getLength('cx', this.getVWidth(), 0),
2925
+ cy = this.getLength('cy', this.getVHeight(), 0),
2926
+ rx = this.getLength('rx', this.getVWidth(), 0),
2927
+ ry = this.getLength('ry', this.getVHeight(), 0);
2928
+ if (rx > 0 && ry > 0) {
2929
+ this.shape = new SvgShape().M(cx + rx, cy).A(rx, ry, 0, 0, 1, cx - rx, cy).A(rx, ry, 0, 0, 1, cx + rx, cy).Z();
2930
+ } else {
2931
+ this.shape = new SvgShape();
2932
+ }
2933
+ };
2934
+ var SvgElemLine = function (obj, inherits) {
2935
+ SvgElemBasicShape.call(this, obj, inherits);
2936
+ let x1 = this.getLength('x1', this.getVWidth(), 0),
2937
+ y1 = this.getLength('y1', this.getVHeight(), 0),
2938
+ x2 = this.getLength('x2', this.getVWidth(), 0),
2939
+ y2 = this.getLength('y2', this.getVHeight(), 0);
2940
+ this.shape = new SvgShape().M(x1, y1).L(x2, y2);
2941
+ };
2942
+ var SvgElemPolyline = function (obj, inherits) {
2943
+ SvgElemBasicShape.call(this, obj, inherits);
2944
+ let points = this.getNumberList('points');
2945
+ this.shape = new SvgShape();
2946
+ for (let i = 0; i < points.length - 1; i += 2) {
2947
+ if (i === 0) {
2948
+ this.shape.M(points[i], points[i + 1]);
2949
+ } else {
2950
+ this.shape.L(points[i], points[i + 1]);
2951
+ }
2952
+ }
2953
+ if (points.error) {
2954
+ warningCallback('SvgElemPolygon: unexpected string ' + points.error);
2955
+ }
2956
+ if (points.length % 2 === 1) {
2957
+ warningCallback('SvgElemPolyline: uneven number of coordinates');
2958
+ }
2959
+ };
2960
+ var SvgElemPolygon = function (obj, inherits) {
2961
+ SvgElemBasicShape.call(this, obj, inherits);
2962
+ let points = this.getNumberList('points');
2963
+ this.shape = new SvgShape();
2964
+ for (let i = 0; i < points.length - 1; i += 2) {
2965
+ if (i === 0) {
2966
+ this.shape.M(points[i], points[i + 1]);
2967
+ } else {
2968
+ this.shape.L(points[i], points[i + 1]);
2969
+ }
2970
+ }
2971
+ this.shape.Z();
2972
+ if (points.error) {
2973
+ warningCallback('SvgElemPolygon: unexpected string ' + points.error);
2974
+ }
2975
+ if (points.length % 2 === 1) {
2976
+ warningCallback('SvgElemPolygon: uneven number of coordinates');
2977
+ }
2978
+ };
2979
+ var SvgElemPath = function (obj, inherits) {
2980
+ SvgElemBasicShape.call(this, obj, inherits);
2981
+ this.shape = new SvgShape().path(this.attr('d'));
2982
+ let pathLength = this.getLength('pathLength', this.getViewport());
2983
+ this.pathLength = pathLength > 0 ? pathLength : undefined;
2984
+ this.dashScale = this.pathLength !== undefined ? this.shape.totalLength / this.pathLength : 1;
2985
+ };
2986
+ var SvgElemMarker = function (obj, inherits) {
2987
+ SvgElemHasChildren.call(this, obj, inherits);
2988
+ let width = this.getLength('markerWidth', this.getParentVWidth(), 3),
2989
+ height = this.getLength('markerHeight', this.getParentVHeight(), 3),
2990
+ viewBox = this.getViewbox('viewBox', [0, 0, width, height]);
2991
+ this.getVWidth = function () {
2992
+ return viewBox[2];
2993
+ };
2994
+ this.getVHeight = function () {
2995
+ return viewBox[3];
2996
+ };
2997
+ this.drawMarker = function (isClip, isMask, posArray, strokeWidth) {
2998
+ doc.save();
2999
+ let orient = this.attr('orient'),
3000
+ units = this.attr('markerUnits'),
3001
+ rotate = orient === 'auto' ? posArray[2] : (parseFloat(orient) || 0) * Math.PI / 180,
3002
+ scale = units === 'userSpaceOnUse' ? 1 : strokeWidth;
3003
+ doc.transform(Math.cos(rotate) * scale, Math.sin(rotate) * scale, -Math.sin(rotate) * scale, Math.cos(rotate) * scale, posArray[0], posArray[1]);
3004
+ let refX = this.getLength('refX', this.getVWidth(), 0),
3005
+ refY = this.getLength('refY', this.getVHeight(), 0),
3006
+ aspectRatioMatrix = parseAspectRatio(this.attr('preserveAspectRatio'), width, height, viewBox[2], viewBox[3], 0.5);
3007
+ if (this.get('overflow') === 'hidden') {
3008
+ doc.rect(aspectRatioMatrix[0] * (viewBox[0] + viewBox[2] / 2 - refX) - width / 2, aspectRatioMatrix[3] * (viewBox[1] + viewBox[3] / 2 - refY) - height / 2, width, height).clip();
3009
+ }
3010
+ doc.transform.apply(doc, aspectRatioMatrix);
3011
+ doc.translate(-refX, -refY);
3012
+ let group;
3013
+ if (this.get('opacity') < 1 && !isClip) {
3014
+ group = docBeginGroup(getPageBBox());
3015
+ }
3016
+ this.drawChildren(isClip, isMask);
3017
+ if (group) {
3018
+ docEndGroup(group);
3019
+ doc.fillOpacity(this.get('opacity'));
3020
+ docInsertGroup(group);
3021
+ }
3022
+ doc.restore();
3023
+ };
3024
+ };
3025
+ var SvgElemClipPath = function (obj, inherits) {
3026
+ SvgElemHasChildren.call(this, obj, inherits);
3027
+ this.useMask = function (bBox) {
3028
+ let group = docBeginGroup(getPageBBox());
3029
+ doc.save();
3030
+ if (this.attr('clipPathUnits') === 'objectBoundingBox') {
3031
+ doc.transform(bBox[2] - bBox[0], 0, 0, bBox[3] - bBox[1], bBox[0], bBox[1]);
3032
+ }
3033
+ this.clip();
3034
+ this.drawChildren(true, false);
3035
+ doc.restore();
3036
+ docEndGroup(group);
3037
+ docApplyMask(group, true);
3038
+ };
3039
+ };
3040
+ var SvgElemMask = function (obj, inherits) {
3041
+ SvgElemHasChildren.call(this, obj, inherits);
3042
+ this.useMask = function (bBox) {
3043
+ let group = docBeginGroup(getPageBBox());
3044
+ doc.save();
3045
+ let x, y, w, h;
3046
+ if (this.attr('maskUnits') === 'userSpaceOnUse') {
3047
+ x = this.getLength('x', this.getVWidth(), -0.1 * (bBox[2] - bBox[0]) + bBox[0]);
3048
+ y = this.getLength('y', this.getVHeight(), -0.1 * (bBox[3] - bBox[1]) + bBox[1]);
3049
+ w = this.getLength('width', this.getVWidth(), 1.2 * (bBox[2] - bBox[0]));
3050
+ h = this.getLength('height', this.getVHeight(), 1.2 * (bBox[3] - bBox[1]));
3051
+ } else {
3052
+ x = this.getLength('x', this.getVWidth(), -0.1) * (bBox[2] - bBox[0]) + bBox[0];
3053
+ y = this.getLength('y', this.getVHeight(), -0.1) * (bBox[3] - bBox[1]) + bBox[1];
3054
+ w = this.getLength('width', this.getVWidth(), 1.2) * (bBox[2] - bBox[0]);
3055
+ h = this.getLength('height', this.getVHeight(), 1.2) * (bBox[3] - bBox[1]);
3056
+ }
3057
+ doc.rect(x, y, w, h).clip();
3058
+ if (this.attr('maskContentUnits') === 'objectBoundingBox') {
3059
+ doc.transform(bBox[2] - bBox[0], 0, 0, bBox[3] - bBox[1], bBox[0], bBox[1]);
3060
+ }
3061
+ this.clip();
3062
+ this.drawChildren(false, true);
3063
+ doc.restore();
3064
+ docEndGroup(group);
3065
+ docApplyMask(group, true);
3066
+ };
3067
+ };
3068
+ var SvgElemTextContainer = function (obj, inherits) {
3069
+ SvgElemStylable.call(this, obj, inherits);
3070
+ this.allowedChildren = ['tspan', '#text', '#cdata-section', 'a'];
3071
+ this.isText = true;
3072
+ this.getBoundingShape = function () {
3073
+ let shape = new SvgShape();
3074
+ for (let i = 0; i < this._pos.length; i++) {
3075
+ let pos = this._pos[i];
3076
+ if (!pos.hidden) {
3077
+ let dx0 = pos.ascent * Math.sin(pos.rotate),
3078
+ dy0 = -pos.ascent * Math.cos(pos.rotate),
3079
+ dx1 = pos.descent * Math.sin(pos.rotate),
3080
+ dy1 = -pos.descent * Math.cos(pos.rotate),
3081
+ dx2 = pos.width * Math.cos(pos.rotate),
3082
+ dy2 = pos.width * Math.sin(pos.rotate);
3083
+ shape.M(pos.x + dx0, pos.y + dy0).L(pos.x + dx0 + dx2, pos.y + dy0 + dy2).M(pos.x + dx1 + dx2, pos.y + dy1 + dy2).L(pos.x + dx1, pos.y + dy1);
3084
+ }
3085
+ }
3086
+ return shape;
3087
+ };
3088
+ this.drawTextInDocument = function (isClip, isMask) {
3089
+ if (this.link && !isClip && !isMask) {
3090
+ this.addLink();
3091
+ }
3092
+ if (this.get('text-decoration') === 'underline') {
3093
+ this.decorate(0.05 * this._font.size, -0.075 * this._font.size, isClip, isMask);
3094
+ }
3095
+ if (this.get('text-decoration') === 'overline') {
3096
+ this.decorate(0.05 * this._font.size, getAscent(this._font.font, this._font.size) + 0.075 * this._font.size, isClip, isMask);
3097
+ }
3098
+ let fill = this.getFill(isClip, isMask),
3099
+ stroke = this.getStroke(isClip, isMask),
3100
+ strokeWidth = this.get('stroke-width');
3101
+ if (this._font.fauxBold) {
3102
+ if (!stroke) {
3103
+ stroke = fill;
3104
+ strokeWidth = this._font.size * 0.03;
3105
+ } else {
3106
+ strokeWidth += this._font.size * 0.03;
3107
+ }
3108
+ }
3109
+ let children = this.getChildren();
3110
+ for (let i = 0; i < children.length; i++) {
3111
+ let childElem = children[i];
3112
+ switch (childElem.name) {
3113
+ case 'tspan':
3114
+ case 'textPath':
3115
+ case 'a':
3116
+ if (childElem.get('display') !== 'none') {
3117
+ childElem.drawTextInDocument(isClip, isMask);
3118
+ }
3119
+ break;
3120
+ case '#text':
3121
+ case '#cdata-section':
3122
+ if (this.get('visibility') === 'hidden') {
3123
+ continue;
3124
+ }
3125
+ if (fill || stroke || isClip) {
3126
+ if (fill) {
3127
+ docFillColor(fill);
3128
+ }
3129
+ if (stroke && strokeWidth) {
3130
+ docStrokeColor(stroke);
3131
+ doc.lineWidth(strokeWidth).miterLimit(this.get('stroke-miterlimit')).lineJoin(this.get('stroke-linejoin')).lineCap(this.get('stroke-linecap')).dash(this.get('stroke-dasharray'), {
3132
+ phase: this.get('stroke-dashoffset')
3133
+ });
3134
+ }
3135
+ docBeginText(this._font.font, this._font.size);
3136
+ docSetTextMode(!!fill, !!stroke);
3137
+ for (let j = 0, pos = childElem._pos; j < pos.length; j++) {
3138
+ if (!pos[j].hidden && isNotEqual(pos[j].width, 0)) {
3139
+ let cos = Math.cos(pos[j].rotate),
3140
+ sin = Math.sin(pos[j].rotate),
3141
+ skew = this._font.fauxItalic ? -0.25 : 0;
3142
+ docSetTextMatrix(cos * pos[j].scale, sin * pos[j].scale, cos * skew - sin, sin * skew + cos, pos[j].x, pos[j].y);
3143
+ docWriteGlyph(pos[j].glyph);
3144
+ }
3145
+ }
3146
+ docEndText();
3147
+ }
3148
+ break;
3149
+ }
3150
+ }
3151
+ if (this.get('text-decoration') === 'line-through') {
3152
+ this.decorate(0.05 * this._font.size, 0.5 * (getAscent(this._font.font, this._font.size) + getDescent(this._font.font, this._font.size)), isClip, isMask);
3153
+ }
3154
+ };
3155
+ this.decorate = function (lineWidth, linePosition, isClip, isMask) {
3156
+ let fill = this.getFill(isClip, isMask),
3157
+ stroke = this.getStroke(isClip, isMask);
3158
+ if (fill) {
3159
+ docFillColor(fill);
3160
+ }
3161
+ if (stroke) {
3162
+ docStrokeColor(stroke);
3163
+ doc.lineWidth(this.get('stroke-width')).miterLimit(this.get('stroke-miterlimit')).lineJoin(this.get('stroke-linejoin')).lineCap(this.get('stroke-linecap')).dash(this.get('stroke-dasharray'), {
3164
+ phase: this.get('stroke-dashoffset')
3165
+ });
3166
+ }
3167
+ for (let j = 0, pos = this._pos; j < pos.length; j++) {
3168
+ if (!pos[j].hidden && isNotEqual(pos[j].width, 0)) {
3169
+ let dx0 = (linePosition + lineWidth / 2) * Math.sin(pos[j].rotate),
3170
+ dy0 = -(linePosition + lineWidth / 2) * Math.cos(pos[j].rotate),
3171
+ dx1 = (linePosition - lineWidth / 2) * Math.sin(pos[j].rotate),
3172
+ dy1 = -(linePosition - lineWidth / 2) * Math.cos(pos[j].rotate),
3173
+ dx2 = pos[j].width * Math.cos(pos[j].rotate),
3174
+ dy2 = pos[j].width * Math.sin(pos[j].rotate);
3175
+ new SvgShape().M(pos[j].x + dx0, pos[j].y + dy0).L(pos[j].x + dx0 + dx2, pos[j].y + dy0 + dy2).L(pos[j].x + dx1 + dx2, pos[j].y + dy1 + dy2).L(pos[j].x + dx1, pos[j].y + dy1).Z().insertInDocument();
3176
+ if (fill && stroke) {
3177
+ doc.fillAndStroke();
3178
+ } else if (fill) {
3179
+ doc.fill();
3180
+ } else if (stroke) {
3181
+ doc.stroke();
3182
+ }
3183
+ }
3184
+ }
3185
+ };
3186
+ };
3187
+ var SvgElemTextNode = function (obj, inherits) {
3188
+ this.name = obj.nodeName;
3189
+ this.textContent = obj.nodeValue;
3190
+ };
3191
+ var SvgElemTspan = function (obj, inherits) {
3192
+ SvgElemTextContainer.call(this, obj, inherits);
3193
+ };
3194
+ var SvgElemTextPath = function (obj, inherits) {
3195
+ SvgElemTextContainer.call(this, obj, inherits);
3196
+ let pathObject, pathLength, temp;
3197
+ if ((temp = this.attr('path')) && temp.trim() !== '') {
3198
+ let pathLength = this.getLength('pathLength', this.getViewport());
3199
+ this.pathObject = new SvgShape().path(temp);
3200
+ this.pathLength = pathLength > 0 ? pathLength : this.pathObject.totalLength;
3201
+ this.pathScale = this.pathObject.totalLength / this.pathLength;
3202
+ } else if ((temp = this.getUrl('href') || this.getUrl('xlink:href')) && temp.nodeName === 'path') {
3203
+ let pathElem = new SvgElemPath(temp, this);
3204
+ this.pathObject = pathElem.shape.clone().transform(pathElem.get('transform'));
3205
+ this.pathLength = this.chooseValue(pathElem.pathLength, this.pathObject.totalLength);
3206
+ this.pathScale = this.pathObject.totalLength / this.pathLength;
3207
+ }
3208
+ };
3209
+ var SvgElemText = function (obj, inherits) {
3210
+ SvgElemTextContainer.call(this, obj, inherits);
3211
+ this.allowedChildren = ['textPath', 'tspan', '#text', '#cdata-section', 'a'];
3212
+ (function (textParentElem) {
3213
+ let processedText = '',
3214
+ remainingText = obj.textContent,
3215
+ textPaths = [],
3216
+ currentChunk = [],
3217
+ currentAnchor,
3218
+ currentDirection,
3219
+ currentX = 0,
3220
+ currentY = 0;
3221
+ function doAnchoring() {
3222
+ if (currentChunk.length) {
3223
+ let last = currentChunk[currentChunk.length - 1];
3224
+ let first = currentChunk[0];
3225
+ let width = last.x + last.width - first.x;
3226
+ let anchordx = {
3227
+ 'startltr': 0,
3228
+ 'middleltr': 0.5,
3229
+ 'endltr': 1,
3230
+ 'startrtl': 1,
3231
+ 'middlertl': 0.5,
3232
+ 'endrtl': 0
3233
+ }[currentAnchor + currentDirection] * width || 0;
3234
+ for (let i = 0; i < currentChunk.length; i++) {
3235
+ currentChunk[i].x -= anchordx;
3236
+ }
3237
+ }
3238
+ currentChunk = [];
3239
+ }
3240
+ function adjustLength(pos, length, spacingAndGlyphs) {
3241
+ let firstChar = pos[0],
3242
+ lastChar = pos[pos.length - 1],
3243
+ startX = firstChar.x,
3244
+ endX = lastChar.x + lastChar.width;
3245
+ if (spacingAndGlyphs) {
3246
+ let textScale = length / (endX - startX);
3247
+ if (textScale > 0 && textScale < Infinity) {
3248
+ for (let j = 0; j < pos.length; j++) {
3249
+ pos[j].x = startX + textScale * (pos[j].x - startX);
3250
+ pos[j].scale *= textScale;
3251
+ pos[j].width *= textScale;
3252
+ }
3253
+ }
3254
+ } else {
3255
+ if (pos.length >= 2) {
3256
+ let spaceDiff = (length - (endX - startX)) / (pos.length - 1);
3257
+ for (let j = 0; j < pos.length; j++) {
3258
+ pos[j].x += j * spaceDiff;
3259
+ }
3260
+ }
3261
+ }
3262
+ currentX += length - (endX - startX);
3263
+ }
3264
+ function recursive(currentElem, parentElem) {
3265
+ currentElem._x = combineArrays(currentElem.getLengthList('x', currentElem.getVWidth()), parentElem ? parentElem._x.slice(parentElem._pos.length) : []);
3266
+ currentElem._y = combineArrays(currentElem.getLengthList('y', currentElem.getVHeight()), parentElem ? parentElem._y.slice(parentElem._pos.length) : []);
3267
+ currentElem._dx = combineArrays(currentElem.getLengthList('dx', currentElem.getVWidth()), parentElem ? parentElem._dx.slice(parentElem._pos.length) : []);
3268
+ currentElem._dy = combineArrays(currentElem.getLengthList('dy', currentElem.getVHeight()), parentElem ? parentElem._dy.slice(parentElem._pos.length) : []);
3269
+ currentElem._rot = combineArrays(currentElem.getNumberList('rotate'), parentElem ? parentElem._rot.slice(parentElem._pos.length) : []);
3270
+ currentElem._defRot = currentElem.chooseValue(currentElem._rot[currentElem._rot.length - 1], parentElem && parentElem._defRot, 0);
3271
+ if (currentElem.name === 'textPath') {
3272
+ currentElem._y = [];
3273
+ }
3274
+ let fontOptions = {
3275
+ fauxItalic: false,
3276
+ fauxBold: false
3277
+ },
3278
+ fontNameorLink = fontCallback(currentElem.get('font-family'), currentElem.get('font-weight') === 'bold', currentElem.get('font-style') === 'italic', fontOptions);
3279
+ try {
3280
+ doc.font(fontNameorLink);
3281
+ } catch (e) {
3282
+ warningCallback('SVGElemText: failed to open font "' + fontNameorLink + '" in PDFKit');
3283
+ }
3284
+ currentElem._pos = [];
3285
+ currentElem._index = 0;
3286
+ currentElem._font = {
3287
+ font: doc._font,
3288
+ size: currentElem.get('font-size'),
3289
+ fauxItalic: fontOptions.fauxItalic,
3290
+ fauxBold: fontOptions.fauxBold
3291
+ };
3292
+ let textLength = currentElem.getLength('textLength', currentElem.getVWidth(), undefined),
3293
+ spacingAndGlyphs = currentElem.attr('lengthAdjust') === 'spacingAndGlyphs',
3294
+ wordSpacing = currentElem.get('word-spacing'),
3295
+ letterSpacing = currentElem.get('letter-spacing'),
3296
+ textAnchor = currentElem.get('text-anchor'),
3297
+ textDirection = currentElem.get('direction'),
3298
+ baseline = getBaseline(currentElem._font.font, currentElem._font.size, currentElem.get('alignment-baseline') || currentElem.get('dominant-baseline'), currentElem.get('baseline-shift'));
3299
+ if (currentElem.name === 'textPath') {
3300
+ doAnchoring();
3301
+ currentX = currentY = 0;
3302
+ }
3303
+ let children = currentElem.getChildren();
3304
+ for (let i = 0; i < children.length; i++) {
3305
+ let childElem = children[i];
3306
+ switch (childElem.name) {
3307
+ case 'tspan':
3308
+ case 'textPath':
3309
+ case 'a':
3310
+ recursive(childElem, currentElem);
3311
+ break;
3312
+ case '#text':
3313
+ case '#cdata-section':
3314
+ let rawText = childElem.textContent,
3315
+ renderedText = rawText,
3316
+ words;
3317
+ childElem._font = currentElem._font;
3318
+ childElem._pos = [];
3319
+ remainingText = remainingText.substring(rawText.length);
3320
+ if (currentElem.get('xml:space') === 'preserve') {
3321
+ renderedText = renderedText.replace(/[\s]/g, ' ');
3322
+ } else {
3323
+ renderedText = renderedText.replace(/[\s]+/g, ' ');
3324
+ if (processedText.match(/[\s]$|^$/)) {
3325
+ renderedText = renderedText.replace(/^[\s]/, '');
3326
+ }
3327
+ if (remainingText.match(/^[\s]*$/)) {
3328
+ renderedText = renderedText.replace(/[\s]$/, '');
3329
+ }
3330
+ }
3331
+ processedText += rawText;
3332
+ if (wordSpacing === 0) {
3333
+ words = [renderedText];
3334
+ } else {
3335
+ words = renderedText.split(/(\s)/);
3336
+ }
3337
+ for (let w = 0; w < words.length; w++) {
3338
+ let pos = getTextPos(currentElem._font.font, currentElem._font.size, words[w]);
3339
+ for (let j = 0; j < pos.length; j++) {
3340
+ let index = currentElem._index,
3341
+ xAttr = currentElem._x[index],
3342
+ yAttr = currentElem._y[index],
3343
+ dxAttr = currentElem._dx[index],
3344
+ dyAttr = currentElem._dy[index],
3345
+ rotAttr = currentElem._rot[index],
3346
+ continuous = !(w === 0 && j === 0);
3347
+ if (xAttr !== undefined) {
3348
+ continuous = false;
3349
+ doAnchoring();
3350
+ currentX = xAttr;
3351
+ }
3352
+ if (yAttr !== undefined) {
3353
+ continuous = false;
3354
+ doAnchoring();
3355
+ currentY = yAttr;
3356
+ }
3357
+ if (dxAttr !== undefined) {
3358
+ continuous = false;
3359
+ currentX += dxAttr;
3360
+ }
3361
+ if (dyAttr !== undefined) {
3362
+ continuous = false;
3363
+ currentY += dyAttr;
3364
+ }
3365
+ if (rotAttr !== undefined || currentElem._defRot !== 0) {
3366
+ continuous = false;
3367
+ }
3368
+ let position = {
3369
+ glyph: pos[j].glyph,
3370
+ rotate: Math.PI / 180 * currentElem.chooseValue(rotAttr, currentElem._defRot),
3371
+ x: currentX + pos[j].xOffset,
3372
+ y: currentY + baseline + pos[j].yOffset,
3373
+ width: pos[j].width,
3374
+ ascent: getAscent(currentElem._font.font, currentElem._font.size),
3375
+ descent: getDescent(currentElem._font.font, currentElem._font.size),
3376
+ scale: 1,
3377
+ hidden: false,
3378
+ continuous: continuous
3379
+ };
3380
+ currentChunk.push(position);
3381
+ childElem._pos.push(position);
3382
+ currentElem._pos.push(position);
3383
+ currentElem._index += pos[j].unicode.length;
3384
+ if (currentChunk.length === 1) {
3385
+ currentAnchor = textAnchor;
3386
+ currentDirection = textDirection;
3387
+ }
3388
+ currentX += pos[j].xAdvance + letterSpacing;
3389
+ currentY += pos[j].yAdvance;
3390
+ }
3391
+ if (words[w] === ' ') {
3392
+ currentX += wordSpacing;
3393
+ }
3394
+ }
3395
+ break;
3396
+ default:
3397
+ remainingText = remainingText.substring(childElem.textContent.length);
3398
+ }
3399
+ }
3400
+ if (textLength && currentElem._pos.length) {
3401
+ adjustLength(currentElem._pos, textLength, spacingAndGlyphs);
3402
+ }
3403
+ if (currentElem.name === 'textPath' || currentElem.name === 'text') {
3404
+ doAnchoring();
3405
+ }
3406
+ if (currentElem.name === 'textPath') {
3407
+ textPaths.push(currentElem);
3408
+ let pathObject = currentElem.pathObject;
3409
+ if (pathObject) {
3410
+ currentX = pathObject.endPoint[0];
3411
+ currentY = pathObject.endPoint[1];
3412
+ }
3413
+ }
3414
+ if (parentElem) {
3415
+ parentElem._pos = parentElem._pos.concat(currentElem._pos);
3416
+ parentElem._index += currentElem._index;
3417
+ }
3418
+ }
3419
+ function textOnPath(currentElem) {
3420
+ let pathObject = currentElem.pathObject,
3421
+ pathLength = currentElem.pathLength,
3422
+ pathScale = currentElem.pathScale;
3423
+ if (pathObject) {
3424
+ let textOffset = currentElem.getLength('startOffset', pathLength, 0);
3425
+ for (let j = 0; j < currentElem._pos.length; j++) {
3426
+ let charMidX = textOffset + currentElem._pos[j].x + 0.5 * currentElem._pos[j].width;
3427
+ if (charMidX > pathLength || charMidX < 0) {
3428
+ currentElem._pos[j].hidden = true;
3429
+ } else {
3430
+ let pointOnPath = pathObject.getPointAtLength(charMidX * pathScale);
3431
+ if (isNotEqual(pathScale, 1)) {
3432
+ currentElem._pos[j].scale *= pathScale;
3433
+ currentElem._pos[j].width *= pathScale;
3434
+ }
3435
+ currentElem._pos[j].x = pointOnPath[0] - 0.5 * currentElem._pos[j].width * Math.cos(pointOnPath[2]) - currentElem._pos[j].y * Math.sin(pointOnPath[2]);
3436
+ currentElem._pos[j].y = pointOnPath[1] - 0.5 * currentElem._pos[j].width * Math.sin(pointOnPath[2]) + currentElem._pos[j].y * Math.cos(pointOnPath[2]);
3437
+ currentElem._pos[j].rotate = pointOnPath[2] + currentElem._pos[j].rotate;
3438
+ currentElem._pos[j].continuous = false;
3439
+ }
3440
+ }
3441
+ } else {
3442
+ for (let j = 0; j < currentElem._pos.length; j++) {
3443
+ currentElem._pos[j].hidden = true;
3444
+ }
3445
+ }
3446
+ }
3447
+ recursive(textParentElem, null);
3448
+ for (let i = 0; i < textPaths.length; i++) {
3449
+ textOnPath(textPaths[i]);
3450
+ }
3451
+ })(this);
3452
+ this.getTransformation = function () {
3453
+ return this.get('transform');
3454
+ };
3455
+ this.drawInDocument = function (isClip, isMask) {
3456
+ doc.save();
3457
+ this.transform();
3458
+ this.clip();
3459
+ let masked = this.mask(),
3460
+ group;
3461
+ if (masked) {
3462
+ group = docBeginGroup(getPageBBox());
3463
+ }
3464
+ this.drawTextInDocument(isClip, isMask);
3465
+ if (group) {
3466
+ docEndGroup(group);
3467
+ docInsertGroup(group);
3468
+ }
3469
+ doc.restore();
3470
+ };
3471
+ };
3472
+ options = options || {};
3473
+ var pxToPt = options.assumePt ? 1 : 72 / 96,
3474
+ // 1px = 72/96pt, but only if assumePt is false
3475
+ viewportWidth = (options.width || doc.page.width) / pxToPt,
3476
+ viewportHeight = (options.height || doc.page.height) / pxToPt,
3477
+ preserveAspectRatio = options.preserveAspectRatio || null,
3478
+ // default to null so that the attr can override if not passed
3479
+ useCSS = options.useCSS && typeof SVGElement !== 'undefined' && svg instanceof SVGElement && typeof getComputedStyle === 'function',
3480
+ warningCallback = options.warningCallback,
3481
+ fontCallback = options.fontCallback,
3482
+ imageCallback = options.imageCallback,
3483
+ colorCallback = options.colorCallback,
3484
+ documentCallback = options.documentCallback,
3485
+ precision = Math.ceil(Math.max(1, options.precision)) || 3,
3486
+ groupStack = [],
3487
+ documentCache = {},
3488
+ links = [],
3489
+ styleRules = [];
3490
+ if (typeof warningCallback !== 'function') {
3491
+ warningCallback = function (str) {
3492
+ if (typeof console !== undefined && typeof console.warn === 'function') {
3493
+ console.warn(str);
3494
+ }
3495
+ };
3496
+ }
3497
+ if (typeof fontCallback !== 'function') {
3498
+ fontCallback = function (family, bold, italic, fontOptions) {
3499
+ // Check if the font is already registered in the document
3500
+ if (bold && italic) {
3501
+ if (doc._registeredFonts.hasOwnProperty(family + '-BoldItalic')) {
3502
+ return family + '-BoldItalic';
3503
+ } else if (doc._registeredFonts.hasOwnProperty(family + '-Italic')) {
3504
+ fontOptions.fauxBold = true;
3505
+ return family + '-Italic';
3506
+ } else if (doc._registeredFonts.hasOwnProperty(family + '-Bold')) {
3507
+ fontOptions.fauxItalic = true;
3508
+ return family + '-Bold';
3509
+ } else if (doc._registeredFonts.hasOwnProperty(family)) {
3510
+ fontOptions.fauxBold = true;
3511
+ fontOptions.fauxItalic = true;
3512
+ return family;
3513
+ }
3514
+ }
3515
+ if (bold && !italic) {
3516
+ if (doc._registeredFonts.hasOwnProperty(family + '-Bold')) {
3517
+ return family + '-Bold';
3518
+ } else if (doc._registeredFonts.hasOwnProperty(family)) {
3519
+ fontOptions.fauxBold = true;
3520
+ return family;
3521
+ }
3522
+ }
3523
+ if (!bold && italic) {
3524
+ if (doc._registeredFonts.hasOwnProperty(family + '-Italic')) {
3525
+ return family + '-Italic';
3526
+ } else if (doc._registeredFonts.hasOwnProperty(family)) {
3527
+ fontOptions.fauxItalic = true;
3528
+ return family;
3529
+ }
3530
+ }
3531
+ if (!bold && !italic) {
3532
+ if (doc._registeredFonts.hasOwnProperty(family)) {
3533
+ return family;
3534
+ }
3535
+ }
3536
+ // Use standard fonts as fallback
3537
+ if (family.match(/(?:^|,)\s*serif\s*$/)) {
3538
+ if (bold && italic) {
3539
+ return 'Times-BoldItalic';
3540
+ }
3541
+ if (bold && !italic) {
3542
+ return 'Times-Bold';
3543
+ }
3544
+ if (!bold && italic) {
3545
+ return 'Times-Italic';
3546
+ }
3547
+ if (!bold && !italic) {
3548
+ return 'Times-Roman';
3549
+ }
3550
+ } else if (family.match(/(?:^|,)\s*monospace\s*$/)) {
3551
+ if (bold && italic) {
3552
+ return 'Courier-BoldOblique';
3553
+ }
3554
+ if (bold && !italic) {
3555
+ return 'Courier-Bold';
3556
+ }
3557
+ if (!bold && italic) {
3558
+ return 'Courier-Oblique';
3559
+ }
3560
+ if (!bold && !italic) {
3561
+ return 'Courier';
3562
+ }
3563
+ } else if (family.match(/(?:^|,)\s*sans-serif\s*$/) || true) {
3564
+ if (bold && italic) {
3565
+ return 'Helvetica-BoldOblique';
3566
+ }
3567
+ if (bold && !italic) {
3568
+ return 'Helvetica-Bold';
3569
+ }
3570
+ if (!bold && italic) {
3571
+ return 'Helvetica-Oblique';
3572
+ }
3573
+ if (!bold && !italic) {
3574
+ return 'Helvetica';
3575
+ }
3576
+ }
3577
+ };
3578
+ }
3579
+ if (typeof imageCallback !== 'function') {
3580
+ imageCallback = function (link) {
3581
+ return link.replace(/\s+/g, '');
3582
+ };
3583
+ }
3584
+ if (typeof colorCallback !== 'function') {
3585
+ colorCallback = null;
3586
+ } else {
3587
+ for (let color in DefaultColors) {
3588
+ let newColor = colorCallback(DefaultColors[color]);
3589
+ DefaultColors[color][0] = newColor[0];
3590
+ DefaultColors[color][1] = newColor[1];
3591
+ }
3592
+ }
3593
+ if (typeof documentCallback !== 'function') {
3594
+ documentCallback = null;
3595
+ }
3596
+ if (typeof svg === 'string') {
3597
+ svg = parseXml(svg);
3598
+ }
3599
+ if (svg) {
3600
+ let styles = svg.getElementsByTagName('style');
3601
+ for (let i = 0; i < styles.length; i++) {
3602
+ styleRules = styleRules.concat(parseStyleSheet(styles[i].textContent));
3603
+ }
3604
+ let elem = createSVGElement(svg, null);
3605
+ if (typeof elem.drawInDocument === 'function') {
3606
+ if (options.useCSS && !useCSS) {
3607
+ warningCallback('SVGtoPDF: useCSS option can only be used for SVG *elements* in compatible browsers');
3608
+ }
3609
+ let savedFillColor = doc._fillColor;
3610
+ doc.save().translate(x || 0, y || 0).scale(pxToPt);
3611
+ elem.drawInDocument();
3612
+ for (let i = 0; i < links.length; i++) {
3613
+ doc.page.annotations.push(links[i]);
3614
+ }
3615
+ doc.restore();
3616
+ doc._fillColor = savedFillColor;
3617
+ } else {
3618
+ warningCallback('SVGtoPDF: this element can\'t be rendered directly: ' + svg.nodeName);
3619
+ }
3620
+ } else {
3621
+ warningCallback('SVGtoPDF: the input does not look like a valid SVG');
3622
+ }
3623
+ };
3624
+ if (typeof module !== 'undefined' && module && typeof module.exports !== 'undefined') {
3625
+ module.exports = SVGtoPDF;
3626
+ }