pdfmake 0.2.4 → 0.3.0-beta.2

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 (128) hide show
  1. package/CHANGELOG.md +10 -27
  2. package/README.md +11 -7
  3. package/build/pdfmake.js +44733 -42435
  4. package/build/pdfmake.js.map +1 -1
  5. package/build/pdfmake.min.js +2 -2
  6. package/build/pdfmake.min.js.map +1 -1
  7. package/build/standard-fonts/Courier.js +27 -0
  8. package/build/standard-fonts/Helvetica.js +27 -0
  9. package/build/standard-fonts/Symbol.js +21 -0
  10. package/build/standard-fonts/Times.js +27 -0
  11. package/build/standard-fonts/ZapfDingbats.js +21 -0
  12. package/build/vfs_fonts.js +2 -2
  13. package/build-vfs.js +2 -2
  14. package/fonts/Roboto/Roboto-Italic.ttf +0 -0
  15. package/fonts/Roboto/Roboto-Medium.ttf +0 -0
  16. package/fonts/Roboto/Roboto-MediumItalic.ttf +0 -0
  17. package/fonts/Roboto/Roboto-Regular.ttf +0 -0
  18. package/fonts/Roboto.js +8 -0
  19. package/js/3rd-party/svg-to-pdfkit/source.js +4301 -0
  20. package/js/3rd-party/svg-to-pdfkit.js +11 -0
  21. package/js/DocMeasure.js +758 -0
  22. package/js/DocPreprocessor.js +291 -0
  23. package/js/DocumentContext.js +306 -0
  24. package/js/ElementWriter.js +400 -0
  25. package/js/LayoutBuilder.js +840 -0
  26. package/js/Line.js +125 -0
  27. package/js/OutputDocument.js +86 -0
  28. package/js/OutputDocumentServer.js +34 -0
  29. package/js/PDFDocument.js +190 -0
  30. package/js/PageElementWriter.js +165 -0
  31. package/js/PageSize.js +88 -0
  32. package/js/Printer.js +300 -0
  33. package/js/Renderer.js +463 -0
  34. package/js/SVGMeasure.js +89 -0
  35. package/js/StyleContextStack.js +206 -0
  36. package/js/TableProcessor.js +590 -0
  37. package/js/TextBreaker.js +182 -0
  38. package/js/TextDecorator.js +181 -0
  39. package/js/TextInlines.js +248 -0
  40. package/js/URLResolver.js +82 -0
  41. package/js/base.js +69 -0
  42. package/js/browser-extensions/OutputDocumentBrowser.js +131 -0
  43. package/js/browser-extensions/URLBrowserResolver.js +94 -0
  44. package/js/browser-extensions/fonts/Roboto.js +42 -0
  45. package/js/browser-extensions/index.js +70 -0
  46. package/js/browser-extensions/pdfMake.js +17 -0
  47. package/js/browser-extensions/standard-fonts/Courier.js +42 -0
  48. package/js/browser-extensions/standard-fonts/Helvetica.js +42 -0
  49. package/js/browser-extensions/standard-fonts/Symbol.js +27 -0
  50. package/js/browser-extensions/standard-fonts/Times.js +42 -0
  51. package/js/browser-extensions/standard-fonts/ZapfDingbats.js +27 -0
  52. package/js/browser-extensions/virtual-fs-cjs.js +3 -0
  53. package/js/columnCalculator.js +142 -0
  54. package/js/helpers/node.js +122 -0
  55. package/js/helpers/tools.js +48 -0
  56. package/js/helpers/variableType.js +52 -0
  57. package/js/index.js +21 -0
  58. package/js/qrEnc.js +810 -0
  59. package/js/standardPageSizes.js +57 -0
  60. package/js/tableLayouts.js +127 -0
  61. package/js/virtual-fs.js +77 -0
  62. package/package.json +26 -22
  63. package/src/3rd-party/svg-to-pdfkit.js +2 -2
  64. package/src/DocMeasure.js +703 -0
  65. package/src/DocPreprocessor.js +264 -0
  66. package/src/DocumentContext.js +309 -0
  67. package/src/ElementWriter.js +394 -0
  68. package/src/LayoutBuilder.js +821 -0
  69. package/src/Line.js +114 -0
  70. package/src/OutputDocument.js +78 -0
  71. package/src/OutputDocumentServer.js +26 -0
  72. package/src/PDFDocument.js +174 -0
  73. package/src/PageElementWriter.js +160 -0
  74. package/src/PageSize.js +53 -0
  75. package/src/Printer.js +277 -0
  76. package/src/Renderer.js +405 -0
  77. package/src/SVGMeasure.js +79 -0
  78. package/src/StyleContextStack.js +216 -0
  79. package/src/TableProcessor.js +558 -0
  80. package/src/TextBreaker.js +149 -0
  81. package/src/TextDecorator.js +161 -0
  82. package/src/TextInlines.js +223 -0
  83. package/src/URLResolver.js +72 -0
  84. package/src/base.js +61 -0
  85. package/src/browser-extensions/OutputDocumentBrowser.js +117 -0
  86. package/src/browser-extensions/URLBrowserResolver.js +49 -53
  87. package/src/browser-extensions/fonts/Roboto.js +27 -0
  88. package/src/browser-extensions/index.js +55 -0
  89. package/src/browser-extensions/pdfMake.js +10 -282
  90. package/src/browser-extensions/standard-fonts/Courier.js +27 -0
  91. package/src/browser-extensions/standard-fonts/Helvetica.js +27 -0
  92. package/src/browser-extensions/standard-fonts/Symbol.js +21 -0
  93. package/src/browser-extensions/standard-fonts/Times.js +27 -0
  94. package/src/browser-extensions/standard-fonts/ZapfDingbats.js +21 -0
  95. package/src/browser-extensions/virtual-fs-cjs.js +1 -0
  96. package/src/columnCalculator.js +29 -32
  97. package/src/helpers/node.js +110 -0
  98. package/src/helpers/tools.js +39 -0
  99. package/src/helpers/variableType.js +39 -0
  100. package/src/index.js +16 -0
  101. package/src/qrEnc.js +15 -10
  102. package/src/standardPageSizes.js +1 -3
  103. package/src/tableLayouts.js +100 -0
  104. package/src/virtual-fs.js +66 -0
  105. package/standard-fonts/Courier.js +8 -0
  106. package/standard-fonts/Helvetica.js +9 -0
  107. package/standard-fonts/Symbol.js +5 -0
  108. package/standard-fonts/Times.js +8 -0
  109. package/standard-fonts/ZapfDingbats.js +5 -0
  110. package/src/browser-extensions/virtual-fs.js +0 -55
  111. package/src/docMeasure.js +0 -807
  112. package/src/docPreprocessor.js +0 -255
  113. package/src/documentContext.js +0 -314
  114. package/src/elementWriter.js +0 -322
  115. package/src/fontProvider.js +0 -68
  116. package/src/helpers.js +0 -126
  117. package/src/imageMeasure.js +0 -51
  118. package/src/layoutBuilder.js +0 -807
  119. package/src/line.js +0 -91
  120. package/src/pageElementWriter.js +0 -174
  121. package/src/pdfKitEngine.js +0 -21
  122. package/src/printer.js +0 -705
  123. package/src/styleContextStack.js +0 -179
  124. package/src/svgMeasure.js +0 -70
  125. package/src/tableProcessor.js +0 -561
  126. package/src/textDecorator.js +0 -157
  127. package/src/textTools.js +0 -373
  128. package/src/traversalTracker.js +0 -47
@@ -0,0 +1,4301 @@
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
+
723
+ function docBeginGroup(bbox) {
724
+ let group = new function PDFGroup() {}();
725
+ group.name = 'G' + (doc._groupCount = (doc._groupCount || 0) + 1);
726
+ group.resources = doc.ref();
727
+ group.xobj = doc.ref({
728
+ Type: 'XObject',
729
+ Subtype: 'Form',
730
+ FormType: 1,
731
+ BBox: bbox,
732
+ Group: {
733
+ S: 'Transparency',
734
+ CS: 'DeviceRGB',
735
+ I: true,
736
+ K: false
737
+ },
738
+ Resources: group.resources
739
+ });
740
+ group.xobj.write('');
741
+ group.savedMatrix = doc._ctm;
742
+ group.savedPage = doc.page;
743
+ groupStack.push(group);
744
+ doc._ctm = [1, 0, 0, 1, 0, 0];
745
+ doc.page = {
746
+ width: doc.page.width,
747
+ height: doc.page.height,
748
+ write: function (data) {
749
+ group.xobj.write(data);
750
+ },
751
+ fonts: {},
752
+ xobjects: {},
753
+ ext_gstates: {},
754
+ patterns: {}
755
+ };
756
+ return group;
757
+ }
758
+
759
+ function docEndGroup(group) {
760
+ if (group !== groupStack.pop()) {
761
+ throw 'Group not matching';
762
+ }
763
+
764
+ if (Object.keys(doc.page.fonts).length) {
765
+ group.resources.data.Font = doc.page.fonts;
766
+ }
767
+
768
+ if (Object.keys(doc.page.xobjects).length) {
769
+ group.resources.data.XObject = doc.page.xobjects;
770
+ }
771
+
772
+ if (Object.keys(doc.page.ext_gstates).length) {
773
+ group.resources.data.ExtGState = doc.page.ext_gstates;
774
+ }
775
+
776
+ if (Object.keys(doc.page.patterns).length) {
777
+ group.resources.data.Pattern = doc.page.patterns;
778
+ }
779
+
780
+ group.resources.end();
781
+ group.xobj.end();
782
+ doc._ctm = group.savedMatrix;
783
+ doc.page = group.savedPage;
784
+ }
785
+
786
+ function docInsertGroup(group) {
787
+ doc.page.xobjects[group.name] = group.xobj;
788
+ doc.addContent('/' + group.name + ' Do');
789
+ }
790
+
791
+ function docApplyMask(group, clip) {
792
+ let name = 'M' + (doc._maskCount = (doc._maskCount || 0) + 1);
793
+ let gstate = doc.ref({
794
+ Type: 'ExtGState',
795
+ CA: 1,
796
+ ca: 1,
797
+ BM: 'Normal',
798
+ SMask: {
799
+ S: 'Luminosity',
800
+ G: group.xobj,
801
+ BC: clip ? [0, 0, 0] : [1, 1, 1]
802
+ }
803
+ });
804
+ gstate.end();
805
+ doc.page.ext_gstates[name] = gstate;
806
+ doc.addContent('/' + name + ' gs');
807
+ }
808
+
809
+ function docCreatePattern(group, dx, dy, matrix) {
810
+ let pattern = new function PDFPattern() {}();
811
+ pattern.group = group;
812
+ pattern.dx = dx;
813
+ pattern.dy = dy;
814
+ pattern.matrix = matrix || [1, 0, 0, 1, 0, 0];
815
+ return pattern;
816
+ }
817
+
818
+ function docUsePattern(pattern, stroke) {
819
+ let name = 'P' + (doc._patternCount = (doc._patternCount || 0) + 1);
820
+ let ref = doc.ref({
821
+ Type: 'Pattern',
822
+ PatternType: 1,
823
+ PaintType: 1,
824
+ TilingType: 2,
825
+ BBox: [0, 0, pattern.dx, pattern.dy],
826
+ XStep: pattern.dx,
827
+ YStep: pattern.dy,
828
+ Matrix: multiplyMatrix(doc._ctm, pattern.matrix),
829
+ Resources: {
830
+ ProcSet: ['PDF', 'Text', 'ImageB', 'ImageC', 'ImageI'],
831
+ XObject: function () {
832
+ let temp = {};
833
+ temp[pattern.group.name] = pattern.group.xobj;
834
+ return temp;
835
+ }()
836
+ }
837
+ });
838
+ ref.write('/' + pattern.group.name + ' Do');
839
+ ref.end();
840
+ doc.page.patterns[name] = ref;
841
+
842
+ if (stroke) {
843
+ doc.addContent('/Pattern CS');
844
+ doc.addContent('/' + name + ' SCN');
845
+ } else {
846
+ doc.addContent('/Pattern cs');
847
+ doc.addContent('/' + name + ' scn');
848
+ }
849
+ }
850
+
851
+ function docBeginText(font, size) {
852
+ if (!doc.page.fonts[font.id]) {
853
+ doc.page.fonts[font.id] = font.ref();
854
+ }
855
+
856
+ doc.addContent('BT').addContent('/' + font.id + ' ' + size + ' Tf');
857
+ }
858
+
859
+ function docSetTextMatrix(a, b, c, d, e, f) {
860
+ doc.addContent(validateNumber(a) + ' ' + validateNumber(b) + ' ' + validateNumber(-c) + ' ' + validateNumber(-d) + ' ' + validateNumber(e) + ' ' + validateNumber(f) + ' Tm');
861
+ }
862
+
863
+ function docSetTextMode(fill, stroke) {
864
+ let mode = fill && stroke ? 2 : stroke ? 1 : fill ? 0 : 3;
865
+ doc.addContent(mode + ' Tr');
866
+ }
867
+
868
+ function docWriteGlyph(glyph) {
869
+ doc.addContent('<' + glyph + '> Tj');
870
+ }
871
+
872
+ function docEndText() {
873
+ doc.addContent('ET');
874
+ }
875
+
876
+ function docFillColor(color) {
877
+ if (color[0].constructor.name === 'PDFPattern') {
878
+ doc.fillOpacity(color[1]);
879
+ docUsePattern(color[0], false);
880
+ } else {
881
+ doc.fillColor(color[0], color[1]);
882
+ }
883
+ }
884
+
885
+ function docStrokeColor(color) {
886
+ if (color[0].constructor.name === 'PDFPattern') {
887
+ doc.strokeOpacity(color[1]);
888
+ docUsePattern(color[0], true);
889
+ } else {
890
+ doc.strokeColor(color[0], color[1]);
891
+ }
892
+ }
893
+
894
+ function docInsertLink(x, y, w, h, url) {
895
+ let ref = doc.ref({
896
+ Type: 'Annot',
897
+ Subtype: 'Link',
898
+ Rect: [x, y, w, h],
899
+ Border: [0, 0, 0],
900
+ A: {
901
+ S: 'URI',
902
+ URI: new String(url)
903
+ }
904
+ });
905
+ ref.end();
906
+ links.push(ref);
907
+ }
908
+
909
+ function parseXml(xml) {
910
+ let SvgNode = function (tag, type, value, error) {
911
+ this.error = error;
912
+ this.nodeName = tag;
913
+ this.nodeValue = value;
914
+ this.nodeType = type;
915
+ this.attributes = Object.create(null);
916
+ this.childNodes = [];
917
+ this.parentNode = null;
918
+ this.id = '';
919
+ this.textContent = '';
920
+ this.classList = [];
921
+ };
922
+
923
+ SvgNode.prototype.getAttribute = function (attr) {
924
+ return this.attributes[attr] != null ? this.attributes[attr] : null;
925
+ };
926
+
927
+ SvgNode.prototype.getElementById = function (id) {
928
+ let result = null;
929
+
930
+ (function recursive(node) {
931
+ if (result) {
932
+ return;
933
+ }
934
+
935
+ if (node.nodeType === 1) {
936
+ if (node.id === id) {
937
+ result = node;
938
+ }
939
+
940
+ for (let i = 0; i < node.childNodes.length; i++) {
941
+ recursive(node.childNodes[i]);
942
+ }
943
+ }
944
+ })(this);
945
+
946
+ return result;
947
+ };
948
+
949
+ SvgNode.prototype.getElementsByTagName = function (tag) {
950
+ let result = [];
951
+
952
+ (function recursive(node) {
953
+ if (node.nodeType === 1) {
954
+ if (node.nodeName === tag) {
955
+ result.push(node);
956
+ }
957
+
958
+ for (let i = 0; i < node.childNodes.length; i++) {
959
+ recursive(node.childNodes[i]);
960
+ }
961
+ }
962
+ })(this);
963
+
964
+ return result;
965
+ };
966
+
967
+ let parser = new StringParser(xml.trim()),
968
+ result,
969
+ child,
970
+ error = false;
971
+
972
+ let recursive = function () {
973
+ let temp, child;
974
+
975
+ if (temp = parser.match(/^<([\w:.-]+)\s*/, true)) {
976
+ // Opening tag
977
+ let node = new SvgNode(temp[1], 1, null, error);
978
+
979
+ while (temp = parser.match(/^([\w:.-]+)(?:\s*=\s*"([^"]*)"|\s*=\s*'([^']*)')?\s*/, true)) {
980
+ // Attribute
981
+ let attr = temp[1],
982
+ value = decodeEntities(temp[2] || temp[3] || '');
983
+
984
+ if (!node.attributes[attr]) {
985
+ node.attributes[attr] = value;
986
+
987
+ if (attr === 'id') {
988
+ node.id = value;
989
+ }
990
+
991
+ if (attr === 'class') {
992
+ node.classList = value.split(' ');
993
+ }
994
+ } else {
995
+ warningCallback('parseXml: duplicate attribute "' + attr + '"');
996
+ error = true;
997
+ }
998
+ }
999
+
1000
+ if (parser.match(/^>/)) {
1001
+ // End of opening tag
1002
+ while (child = recursive()) {
1003
+ node.childNodes.push(child);
1004
+ child.parentNode = node;
1005
+ node.textContent += child.nodeType === 3 || child.nodeType === 4 ? child.nodeValue : child.textContent;
1006
+ }
1007
+
1008
+ if (temp = parser.match(/^<\/([\w:.-]+)\s*>/, true)) {
1009
+ // Closing tag
1010
+ if (temp[1] === node.nodeName) {
1011
+ return node;
1012
+ } else {
1013
+ warningCallback('parseXml: tag not matching, opening "' + node.nodeName + '" & closing "' + temp[1] + '"');
1014
+ error = true;
1015
+ return node;
1016
+ }
1017
+ } else {
1018
+ warningCallback('parseXml: tag not matching, opening "' + node.nodeName + '" & not closing');
1019
+ error = true;
1020
+ return node;
1021
+ }
1022
+ } else if (parser.match(/^\/>/)) {
1023
+ // Self-closing tag
1024
+ return node;
1025
+ } else {
1026
+ warningCallback('parseXml: tag could not be parsed "' + node.nodeName + '"');
1027
+ error = true;
1028
+ }
1029
+ } else if (temp = parser.match(/^<!--[\s\S]*?-->/)) {
1030
+ // Comment
1031
+ return new SvgNode(null, 8, temp, error);
1032
+ } else if (temp = parser.match(/^<\?[\s\S]*?\?>/)) {
1033
+ // Processing instructions
1034
+ return new SvgNode(null, 7, temp, error);
1035
+ } else if (temp = parser.match(/^<!DOCTYPE\s*([\s\S]*?)>/)) {
1036
+ // Doctype
1037
+ return new SvgNode(null, 10, temp, error);
1038
+ } else if (temp = parser.match(/^<!\[CDATA\[([\s\S]*?)\]\]>/, true)) {
1039
+ // Cdata node
1040
+ return new SvgNode('#cdata-section', 4, temp[1], error);
1041
+ } else if (temp = parser.match(/^([^<]+)/, true)) {
1042
+ // Text node
1043
+ return new SvgNode('#text', 3, decodeEntities(temp[1]), error);
1044
+ }
1045
+ };
1046
+
1047
+ while (child = recursive()) {
1048
+ if (child.nodeType === 1 && !result) {
1049
+ result = child;
1050
+ } else if (child.nodeType === 1 || child.nodeType === 3 && child.nodeValue.trim() !== '') {
1051
+ warningCallback('parseXml: data after document end has been discarded');
1052
+ }
1053
+ }
1054
+
1055
+ if (parser.matchAll()) {
1056
+ warningCallback('parseXml: parsing error');
1057
+ }
1058
+
1059
+ return result;
1060
+ }
1061
+
1062
+ ;
1063
+
1064
+ function decodeEntities(str) {
1065
+ return str.replace(/&(?:#([0-9]+)|#[xX]([0-9A-Fa-f]+)|([0-9A-Za-z]+));/g, function (mt, m0, m1, m2) {
1066
+ if (m0) {
1067
+ return String.fromCharCode(parseInt(m0, 10));
1068
+ } else if (m1) {
1069
+ return String.fromCharCode(parseInt(m1, 16));
1070
+ } else if (m2 && Entities[m2]) {
1071
+ return String.fromCharCode(Entities[m2]);
1072
+ } else {
1073
+ return mt;
1074
+ }
1075
+ });
1076
+ }
1077
+
1078
+ function parseColor(raw) {
1079
+ let temp, result;
1080
+ raw = (raw || '').trim();
1081
+
1082
+ if (temp = NamedColors[raw]) {
1083
+ result = [temp.slice(), 1];
1084
+ } else if (temp = raw.match(/^rgba\(\s*([0-9]+)\s*,\s*([0-9]+)\s*,\s*([0-9]+)\s*,\s*([0-9.]+)\s*\)$/i)) {
1085
+ temp[1] = parseInt(temp[1]);
1086
+ temp[2] = parseInt(temp[2]);
1087
+ temp[3] = parseInt(temp[3]);
1088
+ temp[4] = parseFloat(temp[4]);
1089
+
1090
+ if (temp[1] < 256 && temp[2] < 256 && temp[3] < 256 && temp[4] <= 1) {
1091
+ result = [temp.slice(1, 4), temp[4]];
1092
+ }
1093
+ } else if (temp = raw.match(/^rgb\(\s*([0-9]+)\s*,\s*([0-9]+)\s*,\s*([0-9]+)\s*\)$/i)) {
1094
+ temp[1] = parseInt(temp[1]);
1095
+ temp[2] = parseInt(temp[2]);
1096
+ temp[3] = parseInt(temp[3]);
1097
+
1098
+ if (temp[1] < 256 && temp[2] < 256 && temp[3] < 256) {
1099
+ result = [temp.slice(1, 4), 1];
1100
+ }
1101
+ } else if (temp = raw.match(/^rgb\(\s*([0-9.]+)%\s*,\s*([0-9.]+)%\s*,\s*([0-9.]+)%\s*\)$/i)) {
1102
+ temp[1] = 2.55 * parseFloat(temp[1]);
1103
+ temp[2] = 2.55 * parseFloat(temp[2]);
1104
+ temp[3] = 2.55 * parseFloat(temp[3]);
1105
+
1106
+ if (temp[1] < 256 && temp[2] < 256 && temp[3] < 256) {
1107
+ result = [temp.slice(1, 4), 1];
1108
+ }
1109
+ } else if (temp = raw.match(/^#([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})$/i)) {
1110
+ result = [[parseInt(temp[1], 16), parseInt(temp[2], 16), parseInt(temp[3], 16)], 1];
1111
+ } else if (temp = raw.match(/^#([0-9a-f])([0-9a-f])([0-9a-f])$/i)) {
1112
+ result = [[0x11 * parseInt(temp[1], 16), 0x11 * parseInt(temp[2], 16), 0x11 * parseInt(temp[3], 16)], 1];
1113
+ }
1114
+
1115
+ return colorCallback ? colorCallback(result, raw) : result;
1116
+ }
1117
+
1118
+ function opacityToColor(color, opacity, isMask) {
1119
+ let newColor = color[0].slice(),
1120
+ newOpacity = color[1] * opacity;
1121
+
1122
+ if (isMask) {
1123
+ for (let i = 0; i < color.length; i++) {
1124
+ newColor[i] *= newOpacity;
1125
+ }
1126
+
1127
+ return [newColor, 1];
1128
+ } else {
1129
+ return [newColor, newOpacity];
1130
+ }
1131
+ }
1132
+
1133
+ function multiplyMatrix() {
1134
+ function multiply(a, b) {
1135
+ 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]];
1136
+ }
1137
+
1138
+ let result = arguments[0];
1139
+
1140
+ for (let i = 1; i < arguments.length; i++) {
1141
+ result = multiply(result, arguments[i]);
1142
+ }
1143
+
1144
+ return result;
1145
+ }
1146
+
1147
+ function transformPoint(p, m) {
1148
+ return [m[0] * p[0] + m[2] * p[1] + m[4], m[1] * p[0] + m[3] * p[1] + m[5]];
1149
+ }
1150
+
1151
+ function getGlobalMatrix() {
1152
+ let ctm = doc._ctm;
1153
+
1154
+ for (let i = groupStack.length - 1; i >= 0; i--) {
1155
+ ctm = multiplyMatrix(groupStack[i].savedMatrix, ctm);
1156
+ }
1157
+
1158
+ return ctm;
1159
+ }
1160
+
1161
+ function getPageBBox() {
1162
+ 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();
1163
+ }
1164
+
1165
+ function inverseMatrix(m) {
1166
+ let dt = m[0] * m[3] - m[1] * m[2];
1167
+ 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];
1168
+ }
1169
+
1170
+ function validateMatrix(m) {
1171
+ let m0 = validateNumber(m[0]),
1172
+ m1 = validateNumber(m[1]),
1173
+ m2 = validateNumber(m[2]),
1174
+ m3 = validateNumber(m[3]),
1175
+ m4 = validateNumber(m[4]),
1176
+ m5 = validateNumber(m[5]);
1177
+
1178
+ if (isNotEqual(m0 * m3 - m1 * m2, 0)) {
1179
+ return [m0, m1, m2, m3, m4, m5];
1180
+ }
1181
+ }
1182
+
1183
+ function solveEquation(curve) {
1184
+ let a = curve[2] || 0,
1185
+ b = curve[1] || 0,
1186
+ c = curve[0] || 0;
1187
+
1188
+ if (isEqual(a, 0) && isEqual(b, 0)) {
1189
+ return [];
1190
+ } else if (isEqual(a, 0)) {
1191
+ return [-c / b];
1192
+ } else {
1193
+ let d = b * b - 4 * a * c;
1194
+
1195
+ if (isNotEqual(d, 0) && d > 0) {
1196
+ return [(-b + Math.sqrt(d)) / (2 * a), (-b - Math.sqrt(d)) / (2 * a)];
1197
+ } else if (isEqual(d, 0)) {
1198
+ return [-b / (2 * a)];
1199
+ } else {
1200
+ return [];
1201
+ }
1202
+ }
1203
+ }
1204
+
1205
+ function getCurveValue(t, curve) {
1206
+ return (curve[0] || 0) + (curve[1] || 0) * t + (curve[2] || 0) * t * t + (curve[3] || 0) * t * t * t;
1207
+ }
1208
+
1209
+ function isEqual(number, ref) {
1210
+ return Math.abs(number - ref) < 1e-10;
1211
+ }
1212
+
1213
+ function isNotEqual(number, ref) {
1214
+ return Math.abs(number - ref) >= 1e-10;
1215
+ }
1216
+
1217
+ function validateNumber(n) {
1218
+ return n > -1e21 && n < 1e21 ? Math.round(n * 1e6) / 1e6 : 0;
1219
+ }
1220
+
1221
+ function isArrayLike(v) {
1222
+ return typeof v === 'object' && v !== null && typeof v.length === 'number';
1223
+ }
1224
+
1225
+ function parseTranform(v) {
1226
+ let parser = new StringParser((v || '').trim()),
1227
+ result = [1, 0, 0, 1, 0, 0],
1228
+ temp;
1229
+
1230
+ while (temp = parser.match(/^([A-Za-z]+)\s*[(]([^(]+)[)]/, true)) {
1231
+ let func = temp[1],
1232
+ nums = [],
1233
+ parser2 = new StringParser(temp[2].trim()),
1234
+ temp2;
1235
+
1236
+ while (temp2 = parser2.matchNumber()) {
1237
+ nums.push(Number(temp2));
1238
+ parser2.matchSeparator();
1239
+ }
1240
+
1241
+ if (func === 'matrix' && nums.length === 6) {
1242
+ result = multiplyMatrix(result, [nums[0], nums[1], nums[2], nums[3], nums[4], nums[5]]);
1243
+ } else if (func === 'translate' && nums.length === 2) {
1244
+ result = multiplyMatrix(result, [1, 0, 0, 1, nums[0], nums[1]]);
1245
+ } else if (func === 'translate' && nums.length === 1) {
1246
+ result = multiplyMatrix(result, [1, 0, 0, 1, nums[0], 0]);
1247
+ } else if (func === 'scale' && nums.length === 2) {
1248
+ result = multiplyMatrix(result, [nums[0], 0, 0, nums[1], 0, 0]);
1249
+ } else if (func === 'scale' && nums.length === 1) {
1250
+ result = multiplyMatrix(result, [nums[0], 0, 0, nums[0], 0, 0]);
1251
+ } else if (func === 'rotate' && nums.length === 3) {
1252
+ let a = nums[0] * Math.PI / 180;
1253
+ 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]]);
1254
+ } else if (func === 'rotate' && nums.length === 1) {
1255
+ let a = nums[0] * Math.PI / 180;
1256
+ result = multiplyMatrix(result, [Math.cos(a), Math.sin(a), -Math.sin(a), Math.cos(a), 0, 0]);
1257
+ } else if (func === 'skewX' && nums.length === 1) {
1258
+ let a = nums[0] * Math.PI / 180;
1259
+ result = multiplyMatrix(result, [1, 0, Math.tan(a), 1, 0, 0]);
1260
+ } else if (func === 'skewY' && nums.length === 1) {
1261
+ let a = nums[0] * Math.PI / 180;
1262
+ result = multiplyMatrix(result, [1, Math.tan(a), 0, 1, 0, 0]);
1263
+ } else {
1264
+ return;
1265
+ }
1266
+
1267
+ parser.matchSeparator();
1268
+ }
1269
+
1270
+ if (parser.matchAll()) {
1271
+ return;
1272
+ }
1273
+
1274
+ return result;
1275
+ }
1276
+
1277
+ function parseAspectRatio(aspectRatio, availWidth, availHeight, elemWidth, elemHeight, initAlign) {
1278
+ let temp = (aspectRatio || '').trim().match(/^(none)$|^x(Min|Mid|Max)Y(Min|Mid|Max)(?:\s+(meet|slice))?$/) || [],
1279
+ ratioType = temp[1] || temp[4] || 'meet',
1280
+ xAlign = temp[2] || 'Mid',
1281
+ yAlign = temp[3] || 'Mid',
1282
+ scaleX = availWidth / elemWidth,
1283
+ scaleY = availHeight / elemHeight,
1284
+ dx = {
1285
+ 'Min': 0,
1286
+ 'Mid': 0.5,
1287
+ 'Max': 1
1288
+ }[xAlign] - (initAlign || 0),
1289
+ dy = {
1290
+ 'Min': 0,
1291
+ 'Mid': 0.5,
1292
+ 'Max': 1
1293
+ }[yAlign] - (initAlign || 0);
1294
+
1295
+ if (ratioType === 'slice') {
1296
+ scaleY = scaleX = Math.max(scaleX, scaleY);
1297
+ } else if (ratioType === 'meet') {
1298
+ scaleY = scaleX = Math.min(scaleX, scaleY);
1299
+ }
1300
+
1301
+ return [scaleX, 0, 0, scaleY, dx * (availWidth - elemWidth * scaleX), dy * (availHeight - elemHeight * scaleY)];
1302
+ }
1303
+
1304
+ function parseStyleAttr(v) {
1305
+ let result = Object.create(null);
1306
+ v = (v || '').trim().split(/;/);
1307
+
1308
+ for (let i = 0; i < v.length; i++) {
1309
+ let key = (v[i].split(':')[0] || '').trim(),
1310
+ value = (v[i].split(':')[1] || '').trim();
1311
+
1312
+ if (key) {
1313
+ result[key] = value;
1314
+ }
1315
+ }
1316
+
1317
+ if (result['marker']) {
1318
+ if (!result['marker-start']) {
1319
+ result['marker-start'] = result['marker'];
1320
+ }
1321
+
1322
+ if (!result['marker-mid']) {
1323
+ result['marker-mid'] = result['marker'];
1324
+ }
1325
+
1326
+ if (!result['marker-end']) {
1327
+ result['marker-end'] = result['marker'];
1328
+ }
1329
+ }
1330
+
1331
+ if (result['font']) {
1332
+ let fontFamily = null,
1333
+ fontSize = null,
1334
+ fontStyle = "normal",
1335
+ fontWeight = "normal",
1336
+ fontVariant = "normal";
1337
+ let parts = result['font'].split(/\s+/);
1338
+
1339
+ for (let i = 0; i < parts.length; i++) {
1340
+ switch (parts[i]) {
1341
+ case "normal":
1342
+ break;
1343
+
1344
+ case "italic":
1345
+ case "oblique":
1346
+ fontStyle = parts[i];
1347
+ break;
1348
+
1349
+ case "small-caps":
1350
+ fontVariant = parts[i];
1351
+ break;
1352
+
1353
+ case "bold":
1354
+ case "bolder":
1355
+ case "lighter":
1356
+ case "100":
1357
+ case "200":
1358
+ case "300":
1359
+ case "400":
1360
+ case "500":
1361
+ case "600":
1362
+ case "700":
1363
+ case "800":
1364
+ case "900":
1365
+ fontWeight = parts[i];
1366
+ break;
1367
+
1368
+ default:
1369
+ if (!fontSize) {
1370
+ fontSize = parts[i].split('/')[0];
1371
+ } else {
1372
+ if (!fontFamily) {
1373
+ fontFamily = parts[i];
1374
+ } else {
1375
+ fontFamily += ' ' + parts[i];
1376
+ }
1377
+ }
1378
+
1379
+ break;
1380
+ }
1381
+ }
1382
+
1383
+ if (!result['font-style']) {
1384
+ result['font-style'] = fontStyle;
1385
+ }
1386
+
1387
+ if (!result['font-variant']) {
1388
+ result['font-variant'] = fontVariant;
1389
+ }
1390
+
1391
+ if (!result['font-weight']) {
1392
+ result['font-weight'] = fontWeight;
1393
+ }
1394
+
1395
+ if (!result['font-size']) {
1396
+ result['font-size'] = fontSize;
1397
+ }
1398
+
1399
+ if (!result['font-family']) {
1400
+ result['font-family'] = fontFamily;
1401
+ }
1402
+ }
1403
+
1404
+ return result;
1405
+ }
1406
+
1407
+ function parseSelector(v) {
1408
+ let parts = v.split(/(?=[.#])/g),
1409
+ ids = [],
1410
+ classes = [],
1411
+ tags = [],
1412
+ temp;
1413
+
1414
+ for (let i = 0; i < parts.length; i++) {
1415
+ if (temp = parts[i].match(/^[#]([_A-Za-z0-9-]+)$/)) {
1416
+ ids.push(temp[1]);
1417
+ } else if (temp = parts[i].match(/^[.]([_A-Za-z0-9-]+)$/)) {
1418
+ classes.push(temp[1]);
1419
+ } else if (temp = parts[i].match(/^([_A-Za-z0-9-]+)$/)) {
1420
+ tags.push(temp[1]);
1421
+ } else if (parts[i] !== '*') {
1422
+ return;
1423
+ }
1424
+ }
1425
+
1426
+ return {
1427
+ tags: tags,
1428
+ ids: ids,
1429
+ classes: classes,
1430
+ specificity: ids.length * 10000 + classes.length * 100 + tags.length
1431
+ };
1432
+ }
1433
+
1434
+ function parseStyleSheet(v) {
1435
+ let parser = new StringParser(v.trim()),
1436
+ rules = [],
1437
+ rule;
1438
+
1439
+ while (rule = parser.match(/^\s*([^\{\}]*?)\s*\{([^\{\}]*?)\}/, true)) {
1440
+ let selectors = rule[1].split(/\s*,\s*/g),
1441
+ css = parseStyleAttr(rule[2]);
1442
+
1443
+ for (let i = 0; i < selectors.length; i++) {
1444
+ let selector = parseSelector(selectors[i]);
1445
+
1446
+ if (selector) {
1447
+ rules.push({
1448
+ selector: selector,
1449
+ css: css
1450
+ });
1451
+ }
1452
+ }
1453
+ }
1454
+
1455
+ return rules;
1456
+ }
1457
+
1458
+ function matchesSelector(elem, selector) {
1459
+ if (elem.nodeType !== 1) {
1460
+ return false;
1461
+ }
1462
+
1463
+ for (let i = 0; i < selector.tags.length; i++) {
1464
+ if (selector.tags[i] !== elem.nodeName) {
1465
+ return false;
1466
+ }
1467
+ }
1468
+
1469
+ for (let i = 0; i < selector.ids.length; i++) {
1470
+ if (selector.ids[i] !== elem.id) {
1471
+ return false;
1472
+ }
1473
+ }
1474
+
1475
+ for (let i = 0; i < selector.classes.length; i++) {
1476
+ if (elem.classList.indexOf(selector.classes[i]) === -1) {
1477
+ return false;
1478
+ }
1479
+ }
1480
+
1481
+ return true;
1482
+ }
1483
+
1484
+ function getStyle(elem) {
1485
+ let result = Object.create(null);
1486
+ let specificities = Object.create(null);
1487
+
1488
+ for (let i = 0; i < styleRules.length; i++) {
1489
+ let rule = styleRules[i];
1490
+
1491
+ if (matchesSelector(elem, rule.selector)) {
1492
+ for (let key in rule.css) {
1493
+ if (!(specificities[key] > rule.selector.specificity)) {
1494
+ result[key] = rule.css[key];
1495
+ specificities[key] = rule.selector.specificity;
1496
+ }
1497
+ }
1498
+ }
1499
+ }
1500
+
1501
+ return result;
1502
+ }
1503
+
1504
+ function combineArrays(array1, array2) {
1505
+ return array1.concat(array2.slice(array1.length));
1506
+ }
1507
+
1508
+ function getAscent(font, size) {
1509
+ return Math.max(font.ascender, (font.bbox[3] || font.bbox.maxY) * (font.scale || 1)) * size / 1000;
1510
+ }
1511
+
1512
+ function getDescent(font, size) {
1513
+ return Math.min(font.descender, (font.bbox[1] || font.bbox.minY) * (font.scale || 1)) * size / 1000;
1514
+ }
1515
+
1516
+ function getXHeight(font, size) {
1517
+ return (font.xHeight || 0.5 * (font.ascender - font.descender)) * size / 1000;
1518
+ }
1519
+
1520
+ function getBaseline(font, size, baseline, shift) {
1521
+ let dy1, dy2;
1522
+
1523
+ switch (baseline) {
1524
+ case 'middle':
1525
+ dy1 = 0.5 * getXHeight(font, size);
1526
+ break;
1527
+
1528
+ case 'central':
1529
+ dy1 = 0.5 * (getDescent(font, size) + getAscent(font, size));
1530
+ break;
1531
+
1532
+ case 'after-edge':
1533
+ case 'text-after-edge':
1534
+ dy1 = getDescent(font, size);
1535
+ break;
1536
+
1537
+ case 'alphabetic':
1538
+ case 'auto':
1539
+ case 'baseline':
1540
+ dy1 = 0;
1541
+ break;
1542
+
1543
+ case 'mathematical':
1544
+ dy1 = 0.5 * getAscent(font, size);
1545
+ break;
1546
+
1547
+ case 'hanging':
1548
+ dy1 = 0.8 * getAscent(font, size);
1549
+ break;
1550
+
1551
+ case 'before-edge':
1552
+ case 'text-before-edge':
1553
+ dy1 = getAscent(font, size);
1554
+ break;
1555
+
1556
+ default:
1557
+ dy1 = 0;
1558
+ break;
1559
+ }
1560
+
1561
+ switch (shift) {
1562
+ case 'baseline':
1563
+ dy2 = 0;
1564
+ break;
1565
+
1566
+ case 'super':
1567
+ dy2 = 0.6 * size;
1568
+ break;
1569
+
1570
+ case 'sub':
1571
+ dy2 = -0.6 * size;
1572
+ break;
1573
+
1574
+ default:
1575
+ dy2 = shift;
1576
+ break;
1577
+ }
1578
+
1579
+ return dy1 - dy2;
1580
+ }
1581
+
1582
+ function getTextPos(font, size, text) {
1583
+ let encoded = font.encode('' + text),
1584
+ hex = encoded[0],
1585
+ pos = encoded[1],
1586
+ data = [];
1587
+
1588
+ for (let i = 0; i < hex.length; i++) {
1589
+ let unicode = font.unicode ? font.unicode[parseInt(hex[i], 16)] : [text.charCodeAt(i)];
1590
+ data.push({
1591
+ glyph: hex[i],
1592
+ unicode: unicode,
1593
+ width: pos[i].advanceWidth * size / 1000,
1594
+ xOffset: pos[i].xOffset * size / 1000,
1595
+ yOffset: pos[i].yOffset * size / 1000,
1596
+ xAdvance: pos[i].xAdvance * size / 1000,
1597
+ yAdvance: pos[i].yAdvance * size / 1000
1598
+ });
1599
+ }
1600
+
1601
+ return data;
1602
+ }
1603
+
1604
+ function createSVGElement(obj, inherits) {
1605
+ switch (obj.nodeName) {
1606
+ case 'use':
1607
+ return new SvgElemUse(obj, inherits);
1608
+
1609
+ case 'symbol':
1610
+ return new SvgElemSymbol(obj, inherits);
1611
+
1612
+ case 'g':
1613
+ return new SvgElemGroup(obj, inherits);
1614
+
1615
+ case 'a':
1616
+ return new SvgElemLink(obj, inherits);
1617
+
1618
+ case 'svg':
1619
+ return new SvgElemSvg(obj, inherits);
1620
+
1621
+ case 'image':
1622
+ return new SVGElemImage(obj, inherits);
1623
+
1624
+ case 'rect':
1625
+ return new SvgElemRect(obj, inherits);
1626
+
1627
+ case 'circle':
1628
+ return new SvgElemCircle(obj, inherits);
1629
+
1630
+ case 'ellipse':
1631
+ return new SvgElemEllipse(obj, inherits);
1632
+
1633
+ case 'line':
1634
+ return new SvgElemLine(obj, inherits);
1635
+
1636
+ case 'polyline':
1637
+ return new SvgElemPolyline(obj, inherits);
1638
+
1639
+ case 'polygon':
1640
+ return new SvgElemPolygon(obj, inherits);
1641
+
1642
+ case 'path':
1643
+ return new SvgElemPath(obj, inherits);
1644
+
1645
+ case 'text':
1646
+ return new SvgElemText(obj, inherits);
1647
+
1648
+ case 'tspan':
1649
+ return new SvgElemTspan(obj, inherits);
1650
+
1651
+ case 'textPath':
1652
+ return new SvgElemTextPath(obj, inherits);
1653
+
1654
+ case '#text':
1655
+ case '#cdata-section':
1656
+ return new SvgElemTextNode(obj, inherits);
1657
+
1658
+ default:
1659
+ return new SvgElem(obj, inherits);
1660
+ }
1661
+ }
1662
+
1663
+ var StringParser = function (str) {
1664
+ this.match = function (exp, all) {
1665
+ let temp = str.match(exp);
1666
+
1667
+ if (!temp || temp.index !== 0) {
1668
+ return;
1669
+ }
1670
+
1671
+ str = str.substring(temp[0].length);
1672
+ return all ? temp : temp[0];
1673
+ };
1674
+
1675
+ this.matchSeparator = function () {
1676
+ return this.match(/^(?:\s*,\s*|\s*|)/);
1677
+ };
1678
+
1679
+ this.matchSpace = function () {
1680
+ return this.match(/^(?:\s*)/);
1681
+ };
1682
+
1683
+ this.matchLengthUnit = function () {
1684
+ return this.match(/^(?:px|pt|cm|mm|in|pc|em|ex|%|)/);
1685
+ };
1686
+
1687
+ this.matchNumber = function () {
1688
+ return this.match(/^(?:[-+]?(?:[0-9]+[.][0-9]+|[0-9]+[.]|[.][0-9]+|[0-9]+)(?:[eE][-+]?[0-9]+)?)/);
1689
+ };
1690
+
1691
+ this.matchAll = function () {
1692
+ return this.match(/^[\s\S]+/);
1693
+ };
1694
+ };
1695
+
1696
+ var BezierSegment = function (p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y) {
1697
+ let divisions = 6 * precision;
1698
+ let equationX = [p1x, -3 * p1x + 3 * c1x, 3 * p1x - 6 * c1x + 3 * c2x, -p1x + 3 * c1x - 3 * c2x + p2x];
1699
+ let equationY = [p1y, -3 * p1y + 3 * c1y, 3 * p1y - 6 * c1y + 3 * c2y, -p1y + 3 * c1y - 3 * c2y + p2y];
1700
+ let derivativeX = [-3 * p1x + 3 * c1x, 6 * p1x - 12 * c1x + 6 * c2x, -3 * p1x + 9 * c1x - 9 * c2x + 3 * p2x];
1701
+ let derivativeY = [-3 * p1y + 3 * c1y, 6 * p1y - 12 * c1y + 6 * c2y, -3 * p1y + 9 * c1y - 9 * c2y + 3 * p2y];
1702
+ let lengthMap = [0];
1703
+
1704
+ for (let i = 1; i <= divisions; i++) {
1705
+ let t = (i - 0.5) / divisions;
1706
+ let dx = getCurveValue(t, derivativeX) / divisions,
1707
+ dy = getCurveValue(t, derivativeY) / divisions,
1708
+ l = Math.sqrt(dx * dx + dy * dy);
1709
+ lengthMap[i] = lengthMap[i - 1] + l;
1710
+ }
1711
+
1712
+ this.totalLength = lengthMap[divisions];
1713
+ this.startPoint = [p1x, p1y, isEqual(p1x, c1x) && isEqual(p1y, c1y) ? Math.atan2(c2y - c1y, c2x - c1x) : Math.atan2(c1y - p1y, c1x - p1x)];
1714
+ this.endPoint = [p2x, p2y, isEqual(c2x, p2x) && isEqual(c2y, p2y) ? Math.atan2(c2y - c1y, c2x - c1x) : Math.atan2(p2y - c2y, p2x - c2x)];
1715
+
1716
+ this.getBoundingBox = function () {
1717
+ let temp;
1718
+ let minX = getCurveValue(0, equationX),
1719
+ minY = getCurveValue(0, equationY),
1720
+ maxX = getCurveValue(1, equationX),
1721
+ maxY = getCurveValue(1, equationY);
1722
+
1723
+ if (minX > maxX) {
1724
+ temp = maxX;
1725
+ maxX = minX;
1726
+ minX = temp;
1727
+ }
1728
+
1729
+ if (minY > maxY) {
1730
+ temp = maxY;
1731
+ maxY = minY;
1732
+ minY = temp;
1733
+ }
1734
+
1735
+ let rootsX = solveEquation(derivativeX);
1736
+
1737
+ for (let i = 0; i < rootsX.length; i++) {
1738
+ if (rootsX[i] >= 0 && rootsX[i] <= 1) {
1739
+ let x = getCurveValue(rootsX[i], equationX);
1740
+
1741
+ if (x < minX) {
1742
+ minX = x;
1743
+ }
1744
+
1745
+ if (x > maxX) {
1746
+ maxX = x;
1747
+ }
1748
+ }
1749
+ }
1750
+
1751
+ let rootsY = solveEquation(derivativeY);
1752
+
1753
+ for (let i = 0; i < rootsY.length; i++) {
1754
+ if (rootsY[i] >= 0 && rootsY[i] <= 1) {
1755
+ let y = getCurveValue(rootsY[i], equationY);
1756
+
1757
+ if (y < minY) {
1758
+ minY = y;
1759
+ }
1760
+
1761
+ if (y > maxY) {
1762
+ maxY = y;
1763
+ }
1764
+ }
1765
+ }
1766
+
1767
+ return [minX, minY, maxX, maxY];
1768
+ };
1769
+
1770
+ this.getPointAtLength = function (l) {
1771
+ if (isEqual(l, 0)) {
1772
+ return this.startPoint;
1773
+ }
1774
+
1775
+ if (isEqual(l, this.totalLength)) {
1776
+ return this.endPoint;
1777
+ }
1778
+
1779
+ if (l < 0 || l > this.totalLength) {
1780
+ return;
1781
+ }
1782
+
1783
+ for (let i = 1; i <= divisions; i++) {
1784
+ let l1 = lengthMap[i - 1],
1785
+ l2 = lengthMap[i];
1786
+
1787
+ if (l1 <= l && l <= l2) {
1788
+ let t = (i - (l2 - l) / (l2 - l1)) / divisions,
1789
+ x = getCurveValue(t, equationX),
1790
+ y = getCurveValue(t, equationY),
1791
+ dx = getCurveValue(t, derivativeX),
1792
+ dy = getCurveValue(t, derivativeY);
1793
+ return [x, y, Math.atan2(dy, dx)];
1794
+ }
1795
+ }
1796
+ };
1797
+ };
1798
+
1799
+ var LineSegment = function (p1x, p1y, p2x, p2y) {
1800
+ this.totalLength = Math.sqrt((p2x - p1x) * (p2x - p1x) + (p2y - p1y) * (p2y - p1y));
1801
+ this.startPoint = [p1x, p1y, Math.atan2(p2y - p1y, p2x - p1x)];
1802
+ this.endPoint = [p2x, p2y, Math.atan2(p2y - p1y, p2x - p1x)];
1803
+
1804
+ this.getBoundingBox = function () {
1805
+ 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])];
1806
+ };
1807
+
1808
+ this.getPointAtLength = function (l) {
1809
+ if (l >= 0 && l <= this.totalLength) {
1810
+ let r = l / this.totalLength || 0,
1811
+ x = this.startPoint[0] + r * (this.endPoint[0] - this.startPoint[0]),
1812
+ y = this.startPoint[1] + r * (this.endPoint[1] - this.startPoint[1]);
1813
+ return [x, y, this.startPoint[2]];
1814
+ }
1815
+ };
1816
+ };
1817
+
1818
+ var SvgShape = function () {
1819
+ this.pathCommands = [];
1820
+ this.pathSegments = [];
1821
+ this.startPoint = null;
1822
+ this.endPoint = null;
1823
+ this.totalLength = 0;
1824
+ let startX = 0,
1825
+ startY = 0,
1826
+ currX = 0,
1827
+ currY = 0,
1828
+ lastCom,
1829
+ lastCtrlX,
1830
+ lastCtrlY;
1831
+
1832
+ this.move = function (x, y) {
1833
+ startX = currX = x;
1834
+ startY = currY = y;
1835
+ return null;
1836
+ };
1837
+
1838
+ this.line = function (x, y) {
1839
+ let segment = new LineSegment(currX, currY, x, y);
1840
+ currX = x;
1841
+ currY = y;
1842
+ return segment;
1843
+ };
1844
+
1845
+ this.curve = function (c1x, c1y, c2x, c2y, x, y) {
1846
+ let segment = new BezierSegment(currX, currY, c1x, c1y, c2x, c2y, x, y);
1847
+ currX = x;
1848
+ currY = y;
1849
+ return segment;
1850
+ };
1851
+
1852
+ this.close = function () {
1853
+ let segment = new LineSegment(currX, currY, startX, startY);
1854
+ currX = startX;
1855
+ currY = startY;
1856
+ return segment;
1857
+ };
1858
+
1859
+ this.addCommand = function (data) {
1860
+ this.pathCommands.push(data);
1861
+ let segment = this[data[0]].apply(this, data.slice(3));
1862
+
1863
+ if (segment) {
1864
+ segment.hasStart = data[1];
1865
+ segment.hasEnd = data[2];
1866
+ this.startPoint = this.startPoint || segment.startPoint;
1867
+ this.endPoint = segment.endPoint;
1868
+ this.pathSegments.push(segment);
1869
+ this.totalLength += segment.totalLength;
1870
+ }
1871
+ };
1872
+
1873
+ this.M = function (x, y) {
1874
+ this.addCommand(['move', true, true, x, y]);
1875
+ lastCom = 'M';
1876
+ return this;
1877
+ };
1878
+
1879
+ this.m = function (x, y) {
1880
+ return this.M(currX + x, currY + y);
1881
+ };
1882
+
1883
+ this.Z = this.z = function () {
1884
+ this.addCommand(['close', true, true]);
1885
+ lastCom = 'Z';
1886
+ return this;
1887
+ };
1888
+
1889
+ this.L = function (x, y) {
1890
+ this.addCommand(['line', true, true, x, y]);
1891
+ lastCom = 'L';
1892
+ return this;
1893
+ };
1894
+
1895
+ this.l = function (x, y) {
1896
+ return this.L(currX + x, currY + y);
1897
+ };
1898
+
1899
+ this.H = function (x) {
1900
+ return this.L(x, currY);
1901
+ };
1902
+
1903
+ this.h = function (x) {
1904
+ return this.L(currX + x, currY);
1905
+ };
1906
+
1907
+ this.V = function (y) {
1908
+ return this.L(currX, y);
1909
+ };
1910
+
1911
+ this.v = function (y) {
1912
+ return this.L(currX, currY + y);
1913
+ };
1914
+
1915
+ this.C = function (c1x, c1y, c2x, c2y, x, y) {
1916
+ this.addCommand(['curve', true, true, c1x, c1y, c2x, c2y, x, y]);
1917
+ lastCom = 'C';
1918
+ lastCtrlX = c2x;
1919
+ lastCtrlY = c2y;
1920
+ return this;
1921
+ };
1922
+
1923
+ this.c = function (c1x, c1y, c2x, c2y, x, y) {
1924
+ return this.C(currX + c1x, currY + c1y, currX + c2x, currY + c2y, currX + x, currY + y);
1925
+ };
1926
+
1927
+ this.S = function (c1x, c1y, x, y) {
1928
+ return this.C(currX + (lastCom === 'C' ? currX - lastCtrlX : 0), currY + (lastCom === 'C' ? currY - lastCtrlY : 0), c1x, c1y, x, y);
1929
+ };
1930
+
1931
+ this.s = function (c1x, c1y, x, y) {
1932
+ return this.C(currX + (lastCom === 'C' ? currX - lastCtrlX : 0), currY + (lastCom === 'C' ? currY - lastCtrlY : 0), currX + c1x, currY + c1y, currX + x, currY + y);
1933
+ };
1934
+
1935
+ this.Q = function (cx, cy, x, y) {
1936
+ let c1x = currX + 2 / 3 * (cx - currX),
1937
+ c1y = currY + 2 / 3 * (cy - currY),
1938
+ c2x = x + 2 / 3 * (cx - x),
1939
+ c2y = y + 2 / 3 * (cy - y);
1940
+ this.addCommand(['curve', true, true, c1x, c1y, c2x, c2y, x, y]);
1941
+ lastCom = 'Q';
1942
+ lastCtrlX = cx;
1943
+ lastCtrlY = cy;
1944
+ return this;
1945
+ };
1946
+
1947
+ this.q = function (c1x, c1y, x, y) {
1948
+ return this.Q(currX + c1x, currY + c1y, currX + x, currY + y);
1949
+ };
1950
+
1951
+ this.T = function (x, y) {
1952
+ return this.Q(currX + (lastCom === 'Q' ? currX - lastCtrlX : 0), currY + (lastCom === 'Q' ? currY - lastCtrlY : 0), x, y);
1953
+ };
1954
+
1955
+ this.t = function (x, y) {
1956
+ return this.Q(currX + (lastCom === 'Q' ? currX - lastCtrlX : 0), currY + (lastCom === 'Q' ? currY - lastCtrlY : 0), currX + x, currY + y);
1957
+ };
1958
+
1959
+ this.A = function (rx, ry, fi, fa, fs, x, y) {
1960
+ if (isEqual(rx, 0) || isEqual(ry, 0)) {
1961
+ this.addCommand(['line', true, true, x, y]);
1962
+ } else {
1963
+ fi = fi * (Math.PI / 180);
1964
+ rx = Math.abs(rx);
1965
+ ry = Math.abs(ry);
1966
+ fa = 1 * !!fa;
1967
+ fs = 1 * !!fs;
1968
+ let x1 = Math.cos(fi) * (currX - x) / 2 + Math.sin(fi) * (currY - y) / 2,
1969
+ y1 = Math.cos(fi) * (currY - y) / 2 - Math.sin(fi) * (currX - x) / 2,
1970
+ lambda = x1 * x1 / (rx * rx) + y1 * y1 / (ry * ry);
1971
+
1972
+ if (lambda > 1) {
1973
+ rx *= Math.sqrt(lambda);
1974
+ ry *= Math.sqrt(lambda);
1975
+ }
1976
+
1977
+ 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)),
1978
+ x2 = (fa === fs ? -1 : 1) * r * rx * y1 / ry,
1979
+ y2 = (fa === fs ? 1 : -1) * r * ry * x1 / rx;
1980
+ let cx = Math.cos(fi) * x2 - Math.sin(fi) * y2 + (currX + x) / 2,
1981
+ cy = Math.sin(fi) * x2 + Math.cos(fi) * y2 + (currY + y) / 2,
1982
+ th1 = Math.atan2((y1 - y2) / ry, (x1 - x2) / rx),
1983
+ th2 = Math.atan2((-y1 - y2) / ry, (-x1 - x2) / rx);
1984
+
1985
+ if (fs === 0 && th2 - th1 > 0) {
1986
+ th2 -= 2 * Math.PI;
1987
+ } else if (fs === 1 && th2 - th1 < 0) {
1988
+ th2 += 2 * Math.PI;
1989
+ }
1990
+
1991
+ let segms = Math.ceil(Math.abs(th2 - th1) / (Math.PI / precision));
1992
+
1993
+ for (let i = 0; i < segms; i++) {
1994
+ let th3 = th1 + i * (th2 - th1) / segms,
1995
+ th4 = th1 + (i + 1) * (th2 - th1) / segms,
1996
+ t = 4 / 3 * Math.tan((th4 - th3) / 4);
1997
+ 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)),
1998
+ c1y = cy + Math.sin(fi) * rx * (Math.cos(th3) - t * Math.sin(th3)) + Math.cos(fi) * ry * (Math.sin(th3) + t * Math.cos(th3)),
1999
+ c2x = cx + Math.cos(fi) * rx * (Math.cos(th4) + t * Math.sin(th4)) - Math.sin(fi) * ry * (Math.sin(th4) - t * Math.cos(th4)),
2000
+ c2y = cy + Math.sin(fi) * rx * (Math.cos(th4) + t * Math.sin(th4)) + Math.cos(fi) * ry * (Math.sin(th4) - t * Math.cos(th4)),
2001
+ endX = cx + Math.cos(fi) * rx * Math.cos(th4) - Math.sin(fi) * ry * Math.sin(th4),
2002
+ endY = cy + Math.sin(fi) * rx * Math.cos(th4) + Math.cos(fi) * ry * Math.sin(th4);
2003
+ this.addCommand(['curve', i === 0, i === segms - 1, c1x, c1y, c2x, c2y, endX, endY]);
2004
+ }
2005
+ }
2006
+
2007
+ lastCom = 'A';
2008
+ return this;
2009
+ };
2010
+
2011
+ this.a = function (rx, ry, fi, fa, fs, x, y) {
2012
+ return this.A(rx, ry, fi, fa, fs, currX + x, currY + y);
2013
+ };
2014
+
2015
+ this.path = function (d) {
2016
+ let command,
2017
+ value,
2018
+ temp,
2019
+ parser = new StringParser((d || '').trim());
2020
+
2021
+ while (command = parser.match(/^[astvzqmhlcASTVZQMHLC]/)) {
2022
+ parser.matchSeparator();
2023
+ let values = [];
2024
+
2025
+ while (value = PathFlags[command + values.length] ? parser.match(/^[01]/) : parser.matchNumber()) {
2026
+ parser.matchSeparator();
2027
+
2028
+ if (values.length === PathArguments[command]) {
2029
+ this[command].apply(this, values);
2030
+ values = [];
2031
+
2032
+ if (command === 'M') {
2033
+ command = 'L';
2034
+ } else if (command === 'm') {
2035
+ command = 'l';
2036
+ }
2037
+ }
2038
+
2039
+ values.push(Number(value));
2040
+ }
2041
+
2042
+ if (values.length === PathArguments[command]) {
2043
+ this[command].apply(this, values);
2044
+ } else {
2045
+ warningCallback('SvgPath: command ' + command + ' with ' + values.length + ' numbers');
2046
+ return;
2047
+ }
2048
+ }
2049
+
2050
+ if (temp = parser.matchAll()) {
2051
+ warningCallback('SvgPath: unexpected string ' + temp);
2052
+ }
2053
+
2054
+ return this;
2055
+ };
2056
+
2057
+ this.getBoundingBox = function () {
2058
+ let bbox = [Infinity, Infinity, -Infinity, -Infinity];
2059
+
2060
+ function addBounds(bbox1) {
2061
+ if (bbox1[0] < bbox[0]) {
2062
+ bbox[0] = bbox1[0];
2063
+ }
2064
+
2065
+ if (bbox1[2] > bbox[2]) {
2066
+ bbox[2] = bbox1[2];
2067
+ }
2068
+
2069
+ if (bbox1[1] < bbox[1]) {
2070
+ bbox[1] = bbox1[1];
2071
+ }
2072
+
2073
+ if (bbox1[3] > bbox[3]) {
2074
+ bbox[3] = bbox1[3];
2075
+ }
2076
+ }
2077
+
2078
+ for (let i = 0; i < this.pathSegments.length; i++) {
2079
+ addBounds(this.pathSegments[i].getBoundingBox());
2080
+ }
2081
+
2082
+ if (bbox[0] === Infinity) {
2083
+ bbox[0] = 0;
2084
+ }
2085
+
2086
+ if (bbox[1] === Infinity) {
2087
+ bbox[1] = 0;
2088
+ }
2089
+
2090
+ if (bbox[2] === -Infinity) {
2091
+ bbox[2] = 0;
2092
+ }
2093
+
2094
+ if (bbox[3] === -Infinity) {
2095
+ bbox[3] = 0;
2096
+ }
2097
+
2098
+ return bbox;
2099
+ };
2100
+
2101
+ this.getPointAtLength = function (l) {
2102
+ if (l >= 0 && l <= this.totalLength) {
2103
+ let temp;
2104
+
2105
+ for (let i = 0; i < this.pathSegments.length; i++) {
2106
+ if (temp = this.pathSegments[i].getPointAtLength(l)) {
2107
+ return temp;
2108
+ }
2109
+
2110
+ l -= this.pathSegments[i].totalLength;
2111
+ }
2112
+
2113
+ return this.endPoint;
2114
+ }
2115
+ };
2116
+
2117
+ this.transform = function (m) {
2118
+ this.pathSegments = [];
2119
+ this.startPoint = null;
2120
+ this.endPoint = null;
2121
+ this.totalLength = 0;
2122
+
2123
+ for (let i = 0; i < this.pathCommands.length; i++) {
2124
+ let data = this.pathCommands.shift();
2125
+
2126
+ for (let j = 3; j < data.length; j += 2) {
2127
+ let p = transformPoint([data[j], data[j + 1]], m);
2128
+ data[j] = p[0];
2129
+ data[j + 1] = p[1];
2130
+ }
2131
+
2132
+ this.addCommand(data);
2133
+ }
2134
+
2135
+ return this;
2136
+ };
2137
+
2138
+ this.mergeShape = function (shape) {
2139
+ for (let i = 0; i < shape.pathCommands.length; i++) {
2140
+ this.addCommand(shape.pathCommands[i].slice());
2141
+ }
2142
+
2143
+ return this;
2144
+ };
2145
+
2146
+ this.clone = function () {
2147
+ return new SvgShape().mergeShape(this);
2148
+ };
2149
+
2150
+ this.insertInDocument = function () {
2151
+ for (let i = 0; i < this.pathCommands.length; i++) {
2152
+ let command = this.pathCommands[i][0],
2153
+ values = this.pathCommands[i].slice(3);
2154
+
2155
+ switch (command) {
2156
+ case 'move':
2157
+ doc.moveTo(values[0], values[1]);
2158
+ break;
2159
+
2160
+ case 'line':
2161
+ doc.lineTo(values[0], values[1]);
2162
+ break;
2163
+
2164
+ case 'curve':
2165
+ doc.bezierCurveTo(values[0], values[1], values[2], values[3], values[4], values[5]);
2166
+ break;
2167
+
2168
+ case 'close':
2169
+ doc.closePath();
2170
+ break;
2171
+ }
2172
+ }
2173
+ };
2174
+
2175
+ this.getSubPaths = function () {
2176
+ let subPaths = [],
2177
+ shape = new SvgShape();
2178
+
2179
+ for (let i = 0; i < this.pathCommands.length; i++) {
2180
+ let data = this.pathCommands[i],
2181
+ command = this.pathCommands[i][0];
2182
+
2183
+ if (command === 'move' && i !== 0) {
2184
+ subPaths.push(shape);
2185
+ shape = new SvgShape();
2186
+ }
2187
+
2188
+ shape.addCommand(data);
2189
+ }
2190
+
2191
+ subPaths.push(shape);
2192
+ return subPaths;
2193
+ };
2194
+
2195
+ this.getMarkers = function () {
2196
+ let markers = [],
2197
+ subPaths = this.getSubPaths();
2198
+
2199
+ for (let i = 0; i < subPaths.length; i++) {
2200
+ let subPath = subPaths[i],
2201
+ subPathMarkers = [];
2202
+
2203
+ for (let j = 0; j < subPath.pathSegments.length; j++) {
2204
+ let segment = subPath.pathSegments[j];
2205
+
2206
+ if (isNotEqual(segment.totalLength, 0) || j === 0 || j === subPath.pathSegments.length - 1) {
2207
+ if (segment.hasStart) {
2208
+ let startMarker = segment.getPointAtLength(0),
2209
+ prevEndMarker = subPathMarkers.pop();
2210
+
2211
+ if (prevEndMarker) {
2212
+ startMarker[2] = 0.5 * (prevEndMarker[2] + startMarker[2]);
2213
+ }
2214
+
2215
+ subPathMarkers.push(startMarker);
2216
+ }
2217
+
2218
+ if (segment.hasEnd) {
2219
+ let endMarker = segment.getPointAtLength(segment.totalLength);
2220
+ subPathMarkers.push(endMarker);
2221
+ }
2222
+ }
2223
+ }
2224
+
2225
+ markers = markers.concat(subPathMarkers);
2226
+ }
2227
+
2228
+ return markers;
2229
+ };
2230
+ };
2231
+
2232
+ var SvgElem = function (obj, inherits) {
2233
+ let styleCache = Object.create(null);
2234
+ let childrenCache = null;
2235
+ this.name = obj.nodeName;
2236
+ this.isOuterElement = obj === svg || !obj.parentNode;
2237
+ this.inherits = inherits || (!this.isOuterElement ? createSVGElement(obj.parentNode, null) : null);
2238
+ this.stack = this.inherits ? this.inherits.stack.concat(obj) : [obj];
2239
+ this.style = parseStyleAttr(typeof obj.getAttribute === 'function' && obj.getAttribute('style'));
2240
+ this.css = useCSS ? getComputedStyle(obj) : getStyle(obj);
2241
+ this.allowedChildren = [];
2242
+
2243
+ this.attr = function (key) {
2244
+ if (typeof obj.getAttribute === 'function') {
2245
+ return obj.getAttribute(key);
2246
+ }
2247
+ };
2248
+
2249
+ this.resolveUrl = function (value) {
2250
+ let temp = (value || '').match(/^\s*(?:url\("(.*)#(.*)"\)|url\('(.*)#(.*)'\)|url\((.*)#(.*)\)|(.*)#(.*))\s*$/) || [];
2251
+ let file = temp[1] || temp[3] || temp[5] || temp[7],
2252
+ id = temp[2] || temp[4] || temp[6] || temp[8];
2253
+
2254
+ if (id) {
2255
+ if (!file) {
2256
+ let svgObj = svg.getElementById(id);
2257
+
2258
+ if (svgObj) {
2259
+ if (this.stack.indexOf(svgObj) === -1) {
2260
+ return svgObj;
2261
+ } else {
2262
+ warningCallback('SVGtoPDF: loop of circular references for id "' + id + '"');
2263
+ return;
2264
+ }
2265
+ }
2266
+ }
2267
+
2268
+ if (documentCallback) {
2269
+ let svgs = documentCache[file];
2270
+
2271
+ if (!svgs) {
2272
+ svgs = documentCallback(file);
2273
+
2274
+ if (!isArrayLike(svgs)) {
2275
+ svgs = [svgs];
2276
+ }
2277
+
2278
+ for (let i = 0; i < svgs.length; i++) {
2279
+ if (typeof svgs[i] === 'string') {
2280
+ svgs[i] = parseXml(svgs[i]);
2281
+ }
2282
+ }
2283
+
2284
+ documentCache[file] = svgs;
2285
+ }
2286
+
2287
+ for (let i = 0; i < svgs.length; i++) {
2288
+ let svgObj = svgs[i].getElementById(id);
2289
+
2290
+ if (svgObj) {
2291
+ if (this.stack.indexOf(svgObj) === -1) {
2292
+ return svgObj;
2293
+ } else {
2294
+ warningCallback('SVGtoPDF: loop of circular references for id "' + file + '#' + id + '"');
2295
+ return;
2296
+ }
2297
+ }
2298
+ }
2299
+ }
2300
+ }
2301
+ };
2302
+
2303
+ this.computeUnits = function (value, unit, percent, isFontSize) {
2304
+ if (unit === '%') {
2305
+ return parseFloat(value) / 100 * (isFontSize || percent != null ? percent : this.getViewport());
2306
+ } else if (unit === 'ex' || unit === 'em') {
2307
+ return value * {
2308
+ 'em': 1,
2309
+ 'ex': 0.5
2310
+ }[unit] * (isFontSize ? percent : this.get('font-size'));
2311
+ } else {
2312
+ return value * {
2313
+ '': 1,
2314
+ 'px': 1,
2315
+ 'pt': 96 / 72,
2316
+ 'cm': 96 / 2.54,
2317
+ 'mm': 96 / 25.4,
2318
+ 'in': 96,
2319
+ 'pc': 96 / 6
2320
+ }[unit];
2321
+ }
2322
+ };
2323
+
2324
+ this.computeLength = function (value, percent, initial, isFontSize) {
2325
+ let parser = new StringParser((value || '').trim()),
2326
+ temp1,
2327
+ temp2;
2328
+
2329
+ if (typeof (temp1 = parser.matchNumber()) === 'string' && typeof (temp2 = parser.matchLengthUnit()) === 'string' && !parser.matchAll()) {
2330
+ return this.computeUnits(temp1, temp2, percent, isFontSize);
2331
+ }
2332
+
2333
+ return initial;
2334
+ };
2335
+
2336
+ this.computeLengthList = function (value, percent, strict) {
2337
+ let parser = new StringParser((value || '').trim()),
2338
+ result = [],
2339
+ temp1,
2340
+ temp2;
2341
+
2342
+ while (typeof (temp1 = parser.matchNumber()) === 'string' && typeof (temp2 = parser.matchLengthUnit()) === 'string') {
2343
+ result.push(this.computeUnits(temp1, temp2, percent));
2344
+ parser.matchSeparator();
2345
+ }
2346
+
2347
+ if (strict && parser.matchAll()) {
2348
+ return;
2349
+ }
2350
+
2351
+ return result;
2352
+ };
2353
+
2354
+ this.getLength = function (key, percent, initial) {
2355
+ return this.computeLength(this.attr(key), percent, initial);
2356
+ };
2357
+
2358
+ this.getLengthList = function (key, percent) {
2359
+ return this.computeLengthList(this.attr(key), percent);
2360
+ };
2361
+
2362
+ this.getUrl = function (key) {
2363
+ return this.resolveUrl(this.attr(key));
2364
+ };
2365
+
2366
+ this.getNumberList = function (key) {
2367
+ let parser = new StringParser((this.attr(key) || '').trim()),
2368
+ result = [],
2369
+ temp;
2370
+
2371
+ while (temp = parser.matchNumber()) {
2372
+ result.push(Number(temp));
2373
+ parser.matchSeparator();
2374
+ }
2375
+
2376
+ result.error = parser.matchAll();
2377
+ return result;
2378
+ };
2379
+
2380
+ this.getViewbox = function (key, initial) {
2381
+ let viewBox = this.getNumberList(key);
2382
+
2383
+ if (viewBox.length === 4 && viewBox[2] >= 0 && viewBox[3] >= 0) {
2384
+ return viewBox;
2385
+ }
2386
+
2387
+ return initial;
2388
+ };
2389
+
2390
+ this.getPercent = function (key, initial) {
2391
+ let value = this.attr(key);
2392
+ let parser = new StringParser((value || '').trim()),
2393
+ temp1,
2394
+ temp2;
2395
+ let number = parser.matchNumber();
2396
+
2397
+ if (!number) {
2398
+ return initial;
2399
+ }
2400
+
2401
+ if (parser.match('%')) {
2402
+ number *= 0.01;
2403
+ }
2404
+
2405
+ if (parser.matchAll()) {
2406
+ return initial;
2407
+ }
2408
+
2409
+ return Math.max(0, Math.min(1, number));
2410
+ };
2411
+
2412
+ this.chooseValue = function (args) {
2413
+ for (let i = 0; i < arguments.length; i++) {
2414
+ if (arguments[i] != null && arguments[i] === arguments[i]) {
2415
+ return arguments[i];
2416
+ }
2417
+ }
2418
+
2419
+ return arguments[arguments.length - 1];
2420
+ };
2421
+
2422
+ this.get = function (key) {
2423
+ if (styleCache[key] !== undefined) {
2424
+ return styleCache[key];
2425
+ }
2426
+
2427
+ let keyInfo = Properties[key] || {},
2428
+ value,
2429
+ result;
2430
+
2431
+ for (let i = 0; i < 3; i++) {
2432
+ switch (i) {
2433
+ case 0:
2434
+ if (key !== 'transform') {
2435
+ // the CSS transform behaves strangely
2436
+ value = this.css[keyInfo.css || key];
2437
+ }
2438
+
2439
+ break;
2440
+
2441
+ case 1:
2442
+ value = this.style[key];
2443
+ break;
2444
+
2445
+ case 2:
2446
+ value = this.attr(key);
2447
+ break;
2448
+ }
2449
+
2450
+ if (value === 'inherit') {
2451
+ result = this.inherits ? this.inherits.get(key) : keyInfo.initial;
2452
+
2453
+ if (result != null) {
2454
+ return styleCache[key] = result;
2455
+ }
2456
+ }
2457
+
2458
+ if (keyInfo.values != null) {
2459
+ result = keyInfo.values[value];
2460
+
2461
+ if (result != null) {
2462
+ return styleCache[key] = result;
2463
+ }
2464
+ }
2465
+
2466
+ if (value != null) {
2467
+ let parsed;
2468
+
2469
+ switch (key) {
2470
+ case 'font-size':
2471
+ result = this.computeLength(value, this.inherits ? this.inherits.get(key) : keyInfo.initial, undefined, true);
2472
+ break;
2473
+
2474
+ case 'baseline-shift':
2475
+ result = this.computeLength(value, this.get('font-size'));
2476
+ break;
2477
+
2478
+ case 'font-family':
2479
+ result = value || undefined;
2480
+ break;
2481
+
2482
+ case 'opacity':
2483
+ case 'stroke-opacity':
2484
+ case 'fill-opacity':
2485
+ case 'stop-opacity':
2486
+ parsed = parseFloat(value);
2487
+
2488
+ if (!isNaN(parsed)) {
2489
+ result = Math.max(0, Math.min(1, parsed));
2490
+ }
2491
+
2492
+ break;
2493
+
2494
+ case 'transform':
2495
+ result = parseTranform(value);
2496
+ break;
2497
+
2498
+ case 'stroke-dasharray':
2499
+ if (value === 'none') {
2500
+ result = [];
2501
+ } else if (parsed = this.computeLengthList(value, this.getViewport(), true)) {
2502
+ let sum = 0,
2503
+ error = false;
2504
+
2505
+ for (let j = 0; j < parsed.length; j++) {
2506
+ if (parsed[j] < 0) {
2507
+ error = true;
2508
+ }
2509
+
2510
+ sum += parsed[j];
2511
+ }
2512
+
2513
+ if (!error) {
2514
+ if (parsed.length % 2 === 1) {
2515
+ parsed = parsed.concat(parsed);
2516
+ }
2517
+
2518
+ result = sum === 0 ? [] : parsed;
2519
+ }
2520
+ }
2521
+
2522
+ break;
2523
+
2524
+ case 'color':
2525
+ if (value === 'none' || value === 'transparent') {
2526
+ result = 'none';
2527
+ } else {
2528
+ result = parseColor(value);
2529
+ }
2530
+
2531
+ break;
2532
+
2533
+ case 'fill':
2534
+ case 'stroke':
2535
+ if (value === 'none' || value === 'transparent') {
2536
+ result = 'none';
2537
+ } else if (value === 'currentColor') {
2538
+ result = this.get('color');
2539
+ } else if (parsed = parseColor(value)) {
2540
+ return parsed;
2541
+ } else if (parsed = (value || '').split(' ')) {
2542
+ let object = this.resolveUrl(parsed[0]),
2543
+ fallbackColor = parseColor(parsed[1]);
2544
+
2545
+ if (object == null) {
2546
+ result = fallbackColor;
2547
+ } else if (object.nodeName === 'linearGradient' || object.nodeName === 'radialGradient') {
2548
+ result = new SvgElemGradient(object, null, fallbackColor);
2549
+ } else if (object.nodeName === 'pattern') {
2550
+ result = new SvgElemPattern(object, null, fallbackColor);
2551
+ } else {
2552
+ result = fallbackColor;
2553
+ }
2554
+ }
2555
+
2556
+ break;
2557
+
2558
+ case 'stop-color':
2559
+ if (value === 'none' || value === 'transparent') {
2560
+ result = 'none';
2561
+ } else if (value === 'currentColor') {
2562
+ result = this.get('color');
2563
+ } else {
2564
+ result = parseColor(value);
2565
+ }
2566
+
2567
+ break;
2568
+
2569
+ case 'marker-start':
2570
+ case 'marker-mid':
2571
+ case 'marker-end':
2572
+ case 'clip-path':
2573
+ case 'mask':
2574
+ if (value === 'none') {
2575
+ result = 'none';
2576
+ } else {
2577
+ result = this.resolveUrl(value);
2578
+ }
2579
+
2580
+ break;
2581
+
2582
+ case 'stroke-width':
2583
+ parsed = this.computeLength(value, this.getViewport());
2584
+
2585
+ if (parsed != null && parsed >= 0) {
2586
+ result = parsed;
2587
+ }
2588
+
2589
+ break;
2590
+
2591
+ case 'stroke-miterlimit':
2592
+ parsed = parseFloat(value);
2593
+
2594
+ if (parsed != null && parsed >= 1) {
2595
+ result = parsed;
2596
+ }
2597
+
2598
+ break;
2599
+
2600
+ case 'word-spacing':
2601
+ case 'letter-spacing':
2602
+ result = this.computeLength(value, this.getViewport());
2603
+ break;
2604
+
2605
+ case 'stroke-dashoffset':
2606
+ result = this.computeLength(value, this.getViewport());
2607
+
2608
+ if (result != null) {
2609
+ if (result < 0) {
2610
+ // fix for crbug.com/660850
2611
+ let dasharray = this.get('stroke-dasharray');
2612
+
2613
+ for (let j = 0; j < dasharray.length; j++) {
2614
+ result += dasharray[j];
2615
+ }
2616
+ }
2617
+ }
2618
+
2619
+ break;
2620
+ }
2621
+
2622
+ if (result != null) {
2623
+ return styleCache[key] = result;
2624
+ }
2625
+ }
2626
+ }
2627
+
2628
+ return styleCache[key] = keyInfo.inherit && this.inherits ? this.inherits.get(key) : keyInfo.initial;
2629
+ };
2630
+
2631
+ this.getChildren = function () {
2632
+ if (childrenCache != null) {
2633
+ return childrenCache;
2634
+ }
2635
+
2636
+ let children = [];
2637
+
2638
+ for (let i = 0; i < obj.childNodes.length; i++) {
2639
+ let child = obj.childNodes[i];
2640
+
2641
+ if (!child.error && this.allowedChildren.indexOf(child.nodeName) !== -1) {
2642
+ children.push(createSVGElement(child, this));
2643
+ }
2644
+ }
2645
+
2646
+ return childrenCache = children;
2647
+ };
2648
+
2649
+ this.getParentVWidth = function () {
2650
+ return this.inherits ? this.inherits.getVWidth() : viewportWidth;
2651
+ };
2652
+
2653
+ this.getParentVHeight = function () {
2654
+ return this.inherits ? this.inherits.getVHeight() : viewportHeight;
2655
+ };
2656
+
2657
+ this.getParentViewport = function () {
2658
+ return Math.sqrt(0.5 * this.getParentVWidth() * this.getParentVWidth() + 0.5 * this.getParentVHeight() * this.getParentVHeight());
2659
+ };
2660
+
2661
+ this.getVWidth = function () {
2662
+ return this.getParentVWidth();
2663
+ };
2664
+
2665
+ this.getVHeight = function () {
2666
+ return this.getParentVHeight();
2667
+ };
2668
+
2669
+ this.getViewport = function () {
2670
+ return Math.sqrt(0.5 * this.getVWidth() * this.getVWidth() + 0.5 * this.getVHeight() * this.getVHeight());
2671
+ };
2672
+
2673
+ this.getBoundingBox = function () {
2674
+ let shape = this.getBoundingShape();
2675
+ return shape.getBoundingBox();
2676
+ };
2677
+ };
2678
+
2679
+ var SvgElemStylable = function (obj, inherits) {
2680
+ SvgElem.call(this, obj, inherits);
2681
+
2682
+ this.transform = function () {
2683
+ doc.transform.apply(doc, this.getTransformation());
2684
+ };
2685
+
2686
+ this.clip = function () {
2687
+ if (this.get('clip-path') !== 'none') {
2688
+ let clipPath = new SvgElemClipPath(this.get('clip-path'), null);
2689
+ clipPath.useMask(this.getBoundingBox());
2690
+ return true;
2691
+ }
2692
+ };
2693
+
2694
+ this.mask = function () {
2695
+ if (this.get('mask') !== 'none') {
2696
+ let mask = new SvgElemMask(this.get('mask'), null);
2697
+ mask.useMask(this.getBoundingBox());
2698
+ return true;
2699
+ }
2700
+ };
2701
+
2702
+ this.getFill = function (isClip, isMask) {
2703
+ let opacity = this.get('opacity'),
2704
+ fill = this.get('fill'),
2705
+ fillOpacity = this.get('fill-opacity');
2706
+
2707
+ if (isClip) {
2708
+ return DefaultColors.white;
2709
+ }
2710
+
2711
+ if (fill !== 'none' && opacity && fillOpacity) {
2712
+ if (fill instanceof SvgElemGradient || fill instanceof SvgElemPattern) {
2713
+ return fill.getPaint(this.getBoundingBox(), fillOpacity * opacity, isClip, isMask);
2714
+ }
2715
+
2716
+ return opacityToColor(fill, fillOpacity * opacity, isMask);
2717
+ }
2718
+ };
2719
+
2720
+ this.getStroke = function (isClip, isMask) {
2721
+ let opacity = this.get('opacity'),
2722
+ stroke = this.get('stroke'),
2723
+ strokeOpacity = this.get('stroke-opacity');
2724
+
2725
+ if (isClip || isEqual(this.get('stroke-width'), 0)) {
2726
+ return;
2727
+ }
2728
+
2729
+ if (stroke !== 'none' && opacity && strokeOpacity) {
2730
+ if (stroke instanceof SvgElemGradient || stroke instanceof SvgElemPattern) {
2731
+ return stroke.getPaint(this.getBoundingBox(), strokeOpacity * opacity, isClip, isMask);
2732
+ }
2733
+
2734
+ return opacityToColor(stroke, strokeOpacity * opacity, isMask);
2735
+ }
2736
+ };
2737
+ };
2738
+
2739
+ var SvgElemHasChildren = function (obj, inherits) {
2740
+ SvgElemStylable.call(this, obj, inherits);
2741
+ this.allowedChildren = ['use', 'g', 'a', 'svg', 'image', 'rect', 'circle', 'ellipse', 'line', 'polyline', 'polygon', 'path', 'text'];
2742
+
2743
+ this.getBoundingShape = function () {
2744
+ let shape = new SvgShape(),
2745
+ children = this.getChildren();
2746
+
2747
+ for (let i = 0; i < children.length; i++) {
2748
+ if (children[i].get('display') !== 'none') {
2749
+ if (typeof children[i].getBoundingShape === 'function') {
2750
+ let childShape = children[i].getBoundingShape().clone();
2751
+
2752
+ if (typeof children[i].getTransformation === 'function') {
2753
+ childShape.transform(children[i].getTransformation());
2754
+ }
2755
+
2756
+ shape.mergeShape(childShape);
2757
+ }
2758
+ }
2759
+ }
2760
+
2761
+ return shape;
2762
+ };
2763
+
2764
+ this.drawChildren = function (isClip, isMask) {
2765
+ let children = this.getChildren();
2766
+
2767
+ for (let i = 0; i < children.length; i++) {
2768
+ if (children[i].get('display') !== 'none') {
2769
+ if (typeof children[i].drawInDocument === 'function') {
2770
+ children[i].drawInDocument(isClip, isMask);
2771
+ }
2772
+ }
2773
+ }
2774
+ };
2775
+ };
2776
+
2777
+ var SvgElemContainer = function (obj, inherits) {
2778
+ SvgElemHasChildren.call(this, obj, inherits);
2779
+
2780
+ this.drawContent = function (isClip, isMask) {
2781
+ this.transform();
2782
+ let clipped = this.clip(),
2783
+ masked = this.mask(),
2784
+ group;
2785
+
2786
+ if ((this.get('opacity') < 1 || clipped || masked) && !isClip) {
2787
+ group = docBeginGroup(getPageBBox());
2788
+ }
2789
+
2790
+ this.drawChildren(isClip, isMask);
2791
+
2792
+ if (group) {
2793
+ docEndGroup(group);
2794
+ doc.fillOpacity(this.get('opacity'));
2795
+ docInsertGroup(group);
2796
+ }
2797
+ };
2798
+ };
2799
+
2800
+ var SvgElemUse = function (obj, inherits) {
2801
+ SvgElemContainer.call(this, obj, inherits);
2802
+ let x = this.getLength('x', this.getVWidth(), 0),
2803
+ y = this.getLength('y', this.getVHeight(), 0),
2804
+ child = this.getUrl('href') || this.getUrl('xlink:href');
2805
+
2806
+ if (child) {
2807
+ child = createSVGElement(child, this);
2808
+ }
2809
+
2810
+ this.getChildren = function () {
2811
+ return child ? [child] : [];
2812
+ };
2813
+
2814
+ this.drawInDocument = function (isClip, isMask) {
2815
+ doc.save();
2816
+ this.drawContent(isClip, isMask);
2817
+ doc.restore();
2818
+ };
2819
+
2820
+ this.getTransformation = function () {
2821
+ return multiplyMatrix(this.get('transform'), [1, 0, 0, 1, x, y]);
2822
+ };
2823
+ };
2824
+
2825
+ var SvgElemSymbol = function (obj, inherits) {
2826
+ SvgElemContainer.call(this, obj, inherits);
2827
+ let width = this.getLength('width', this.getParentVWidth(), this.getParentVWidth()),
2828
+ height = this.getLength('height', this.getParentVHeight(), this.getParentVHeight());
2829
+
2830
+ if (inherits instanceof SvgElemUse) {
2831
+ width = inherits.getLength('width', inherits.getParentVWidth(), width);
2832
+ height = inherits.getLength('height', inherits.getParentVHeight(), height);
2833
+ }
2834
+
2835
+ let aspectRatio = (this.attr('preserveAspectRatio') || '').trim(),
2836
+ viewBox = this.getViewbox('viewBox', [0, 0, width, height]);
2837
+
2838
+ this.getVWidth = function () {
2839
+ return viewBox[2];
2840
+ };
2841
+
2842
+ this.getVHeight = function () {
2843
+ return viewBox[3];
2844
+ };
2845
+
2846
+ this.drawInDocument = function (isClip, isMask) {
2847
+ doc.save();
2848
+ this.drawContent(isClip, isMask);
2849
+ doc.restore();
2850
+ };
2851
+
2852
+ this.getTransformation = function () {
2853
+ return multiplyMatrix(parseAspectRatio(aspectRatio, width, height, viewBox[2], viewBox[3]), [1, 0, 0, 1, -viewBox[0], -viewBox[1]]);
2854
+ };
2855
+ };
2856
+
2857
+ var SvgElemGroup = function (obj, inherits) {
2858
+ SvgElemContainer.call(this, obj, inherits);
2859
+
2860
+ this.drawInDocument = function (isClip, isMask) {
2861
+ doc.save();
2862
+
2863
+ if (this.link && !isClip && !isMask) {
2864
+ this.addLink();
2865
+ }
2866
+
2867
+ this.drawContent(isClip, isMask);
2868
+ doc.restore();
2869
+ };
2870
+
2871
+ this.getTransformation = function () {
2872
+ return this.get('transform');
2873
+ };
2874
+ };
2875
+
2876
+ var SvgElemLink = function (obj, inherits) {
2877
+ if (inherits && inherits.isText) {
2878
+ SvgElemTspan.call(this, obj, inherits);
2879
+ this.allowedChildren = ['textPath', 'tspan', '#text', '#cdata-section', 'a'];
2880
+ } else {
2881
+ SvgElemGroup.call(this, obj, inherits);
2882
+ }
2883
+
2884
+ this.link = this.attr('href') || this.attr('xlink:href');
2885
+
2886
+ this.addLink = function () {
2887
+ if (this.link.match(/^(?:[a-z][a-z0-9+.-]*:|\/\/)?/i) && this.getChildren().length) {
2888
+ let bbox = this.getBoundingShape().transform(getGlobalMatrix()).getBoundingBox();
2889
+ docInsertLink(bbox[0], bbox[1], bbox[2], bbox[3], this.link);
2890
+ }
2891
+ };
2892
+ };
2893
+
2894
+ var SvgElemSvg = function (obj, inherits) {
2895
+ SvgElemContainer.call(this, obj, inherits);
2896
+ let width = this.getLength('width', this.getParentVWidth(), this.getParentVWidth()),
2897
+ height = this.getLength('height', this.getParentVHeight(), this.getParentVHeight()),
2898
+ x = this.getLength('x', this.getParentVWidth(), 0),
2899
+ y = this.getLength('y', this.getParentVHeight(), 0);
2900
+
2901
+ if (inherits instanceof SvgElemUse) {
2902
+ width = inherits.getLength('width', inherits.getParentVWidth(), width);
2903
+ height = inherits.getLength('height', inherits.getParentVHeight(), height);
2904
+ }
2905
+
2906
+ let aspectRatio = this.attr('preserveAspectRatio'),
2907
+ viewBox = this.getViewbox('viewBox', [0, 0, width, height]);
2908
+
2909
+ if (this.isOuterElement && preserveAspectRatio) {
2910
+ x = y = 0;
2911
+ width = viewportWidth;
2912
+ height = viewportHeight;
2913
+ aspectRatio = preserveAspectRatio;
2914
+ }
2915
+
2916
+ this.getVWidth = function () {
2917
+ return viewBox[2];
2918
+ };
2919
+
2920
+ this.getVHeight = function () {
2921
+ return viewBox[3];
2922
+ };
2923
+
2924
+ this.drawInDocument = function (isClip, isMask) {
2925
+ doc.save();
2926
+
2927
+ if (this.get('overflow') === 'hidden') {
2928
+ new SvgShape().M(x, y).L(x + width, y).L(x + width, y + height).L(x, y + height).Z().transform(this.get('transform')).insertInDocument();
2929
+ doc.clip();
2930
+ }
2931
+
2932
+ this.drawContent(isClip, isMask);
2933
+ doc.restore();
2934
+ };
2935
+
2936
+ this.getTransformation = function () {
2937
+ 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]]);
2938
+ };
2939
+ };
2940
+
2941
+ var SVGElemImage = function (obj, inherits) {
2942
+ SvgElemStylable.call(this, obj, inherits);
2943
+ let link = imageCallback(this.attr('href') || this.attr('xlink:href') || ''),
2944
+ x = this.getLength('x', this.getVWidth(), 0),
2945
+ y = this.getLength('y', this.getVHeight(), 0),
2946
+ width = this.getLength('width', this.getVWidth(), 'auto'),
2947
+ height = this.getLength('height', this.getVHeight(), 'auto'),
2948
+ image;
2949
+
2950
+ try {
2951
+ image = doc.openImage(link);
2952
+ } catch (e) {
2953
+ warningCallback('SVGElemImage: failed to open image "' + link + '" in PDFKit');
2954
+ }
2955
+
2956
+ if (image) {
2957
+ if (width === 'auto' && height !== 'auto') {
2958
+ width = height * image.width / image.height;
2959
+ } else if (height === 'auto' && width !== 'auto') {
2960
+ height = width * image.height / image.width;
2961
+ } else if (width === 'auto' && height === 'auto') {
2962
+ width = image.width;
2963
+ height = image.height;
2964
+ }
2965
+ }
2966
+
2967
+ if (width === 'auto' || width < 0) {
2968
+ width = 0;
2969
+ }
2970
+
2971
+ if (height === 'auto' || height < 0) {
2972
+ height = 0;
2973
+ }
2974
+
2975
+ this.getTransformation = function () {
2976
+ return this.get('transform');
2977
+ };
2978
+
2979
+ this.getBoundingShape = function () {
2980
+ return new SvgShape().M(x, y).L(x + width, y).M(x + width, y + height).L(x, y + height);
2981
+ };
2982
+
2983
+ this.drawInDocument = function (isClip, isMask) {
2984
+ if (this.get('visibility') === 'hidden' || !image) {
2985
+ return;
2986
+ }
2987
+
2988
+ doc.save();
2989
+ this.transform();
2990
+
2991
+ if (this.get('overflow') === 'hidden') {
2992
+ doc.rect(x, y, width, height).clip();
2993
+ }
2994
+
2995
+ this.clip();
2996
+ this.mask();
2997
+ doc.translate(x, y);
2998
+ doc.transform.apply(doc, parseAspectRatio(this.attr('preserveAspectRatio'), width, height, image ? image.width : width, image ? image.height : height));
2999
+
3000
+ if (!isClip) {
3001
+ doc.fillOpacity(this.get('opacity'));
3002
+ doc.image(image, 0, 0);
3003
+ } else {
3004
+ doc.rect(0, 0, image.width, image.height);
3005
+ docFillColor(DefaultColors.white).fill();
3006
+ }
3007
+
3008
+ doc.restore();
3009
+ };
3010
+ };
3011
+
3012
+ var SvgElemPattern = function (obj, inherits, fallback) {
3013
+ SvgElemHasChildren.call(this, obj, inherits);
3014
+
3015
+ this.ref = function () {
3016
+ let ref = this.getUrl('href') || this.getUrl('xlink:href');
3017
+
3018
+ if (ref && ref.nodeName === obj.nodeName) {
3019
+ return new SvgElemPattern(ref, inherits, fallback);
3020
+ }
3021
+ }.call(this);
3022
+
3023
+ let _attr = this.attr;
3024
+
3025
+ this.attr = function (key) {
3026
+ let attr = _attr.call(this, key);
3027
+
3028
+ if (attr != null || key === 'href' || key === 'xlink:href') {
3029
+ return attr;
3030
+ }
3031
+
3032
+ return this.ref ? this.ref.attr(key) : null;
3033
+ };
3034
+
3035
+ let _getChildren = this.getChildren;
3036
+
3037
+ this.getChildren = function () {
3038
+ let children = _getChildren.call(this);
3039
+
3040
+ if (children.length > 0) {
3041
+ return children;
3042
+ }
3043
+
3044
+ return this.ref ? this.ref.getChildren() : [];
3045
+ };
3046
+
3047
+ this.getPaint = function (bBox, gOpacity, isClip, isMask) {
3048
+ let bBoxUnitsPattern = this.attr('patternUnits') !== 'userSpaceOnUse',
3049
+ bBoxUnitsContent = this.attr('patternContentUnits') === 'objectBoundingBox',
3050
+ x = this.getLength('x', bBoxUnitsPattern ? 1 : this.getParentVWidth(), 0),
3051
+ y = this.getLength('y', bBoxUnitsPattern ? 1 : this.getParentVHeight(), 0),
3052
+ width = this.getLength('width', bBoxUnitsPattern ? 1 : this.getParentVWidth(), 0),
3053
+ height = this.getLength('height', bBoxUnitsPattern ? 1 : this.getParentVHeight(), 0);
3054
+
3055
+ if (bBoxUnitsContent && !bBoxUnitsPattern) {
3056
+ // Use the same units for pattern & pattern content
3057
+ x = (x - bBox[0]) / (bBox[2] - bBox[0]) || 0;
3058
+ y = (y - bBox[1]) / (bBox[3] - bBox[1]) || 0;
3059
+ width = width / (bBox[2] - bBox[0]) || 0;
3060
+ height = height / (bBox[3] - bBox[1]) || 0;
3061
+ } else if (!bBoxUnitsContent && bBoxUnitsPattern) {
3062
+ x = bBox[0] + x * (bBox[2] - bBox[0]);
3063
+ y = bBox[1] + y * (bBox[3] - bBox[1]);
3064
+ width = width * (bBox[2] - bBox[0]);
3065
+ height = height * (bBox[3] - bBox[1]);
3066
+ }
3067
+
3068
+ let viewBox = this.getViewbox('viewBox', [0, 0, width, height]),
3069
+ aspectRatio = (this.attr('preserveAspectRatio') || '').trim(),
3070
+ aspectRatioMatrix = multiplyMatrix(parseAspectRatio(aspectRatio, width, height, viewBox[2], viewBox[3], 0), [1, 0, 0, 1, -viewBox[0], -viewBox[1]]),
3071
+ matrix = parseTranform(this.attr('patternTransform'));
3072
+
3073
+ if (bBoxUnitsContent) {
3074
+ matrix = multiplyMatrix([bBox[2] - bBox[0], 0, 0, bBox[3] - bBox[1], bBox[0], bBox[1]], matrix);
3075
+ }
3076
+
3077
+ matrix = multiplyMatrix(matrix, [1, 0, 0, 1, x, y]);
3078
+
3079
+ if ((matrix = validateMatrix(matrix)) && (aspectRatioMatrix = validateMatrix(aspectRatioMatrix)) && (width = validateNumber(width)) && (height = validateNumber(height))) {
3080
+ let group = docBeginGroup([0, 0, width, height]);
3081
+ doc.transform.apply(doc, aspectRatioMatrix);
3082
+ this.drawChildren(isClip, isMask);
3083
+ docEndGroup(group);
3084
+ return [docCreatePattern(group, width, height, matrix), gOpacity];
3085
+ } else {
3086
+ return fallback ? [fallback[0], fallback[1] * gOpacity] : undefined;
3087
+ }
3088
+ };
3089
+
3090
+ this.getVWidth = function () {
3091
+ let bBoxUnitsPattern = this.attr('patternUnits') !== 'userSpaceOnUse',
3092
+ width = this.getLength('width', bBoxUnitsPattern ? 1 : this.getParentVWidth(), 0);
3093
+ return this.getViewbox('viewBox', [0, 0, width, 0])[2];
3094
+ };
3095
+
3096
+ this.getVHeight = function () {
3097
+ let bBoxUnitsPattern = this.attr('patternUnits') !== 'userSpaceOnUse',
3098
+ height = this.getLength('height', bBoxUnitsPattern ? 1 : this.getParentVHeight(), 0);
3099
+ return this.getViewbox('viewBox', [0, 0, 0, height])[3];
3100
+ };
3101
+ };
3102
+
3103
+ var SvgElemGradient = function (obj, inherits, fallback) {
3104
+ SvgElem.call(this, obj, inherits);
3105
+ this.allowedChildren = ['stop'];
3106
+
3107
+ this.ref = function () {
3108
+ let ref = this.getUrl('href') || this.getUrl('xlink:href');
3109
+
3110
+ if (ref && ref.nodeName === obj.nodeName) {
3111
+ return new SvgElemGradient(ref, inherits, fallback);
3112
+ }
3113
+ }.call(this);
3114
+
3115
+ let _attr = this.attr;
3116
+
3117
+ this.attr = function (key) {
3118
+ let attr = _attr.call(this, key);
3119
+
3120
+ if (attr != null || key === 'href' || key === 'xlink:href') {
3121
+ return attr;
3122
+ }
3123
+
3124
+ return this.ref ? this.ref.attr(key) : null;
3125
+ };
3126
+
3127
+ let _getChildren = this.getChildren;
3128
+
3129
+ this.getChildren = function () {
3130
+ let children = _getChildren.call(this);
3131
+
3132
+ if (children.length > 0) {
3133
+ return children;
3134
+ }
3135
+
3136
+ return this.ref ? this.ref.getChildren() : [];
3137
+ };
3138
+
3139
+ this.getPaint = function (bBox, gOpacity, isClip, isMask) {
3140
+ let children = this.getChildren();
3141
+
3142
+ if (children.length === 0) {
3143
+ return;
3144
+ }
3145
+
3146
+ if (children.length === 1) {
3147
+ let child = children[0],
3148
+ stopColor = child.get('stop-color');
3149
+
3150
+ if (stopColor === 'none') {
3151
+ return;
3152
+ }
3153
+
3154
+ return opacityToColor(stopColor, child.get('stop-opacity') * gOpacity, isMask);
3155
+ }
3156
+
3157
+ let bBoxUnits = this.attr('gradientUnits') !== 'userSpaceOnUse',
3158
+ matrix = parseTranform(this.attr('gradientTransform')),
3159
+ spread = this.attr('spreadMethod'),
3160
+ grad,
3161
+ x1,
3162
+ x2,
3163
+ y1,
3164
+ y2,
3165
+ r2,
3166
+ nAfter = 0,
3167
+ nBefore = 0,
3168
+ nTotal = 1;
3169
+
3170
+ if (bBoxUnits) {
3171
+ matrix = multiplyMatrix([bBox[2] - bBox[0], 0, 0, bBox[3] - bBox[1], bBox[0], bBox[1]], matrix);
3172
+ }
3173
+
3174
+ if (matrix = validateMatrix(matrix)) {
3175
+ if (this.name === 'linearGradient') {
3176
+ x1 = this.getLength('x1', bBoxUnits ? 1 : this.getVWidth(), 0);
3177
+ x2 = this.getLength('x2', bBoxUnits ? 1 : this.getVWidth(), bBoxUnits ? 1 : this.getVWidth());
3178
+ y1 = this.getLength('y1', bBoxUnits ? 1 : this.getVHeight(), 0);
3179
+ y2 = this.getLength('y2', bBoxUnits ? 1 : this.getVHeight(), 0);
3180
+ } else {
3181
+ x2 = this.getLength('cx', bBoxUnits ? 1 : this.getVWidth(), bBoxUnits ? 0.5 : 0.5 * this.getVWidth());
3182
+ y2 = this.getLength('cy', bBoxUnits ? 1 : this.getVHeight(), bBoxUnits ? 0.5 : 0.5 * this.getVHeight());
3183
+ r2 = this.getLength('r', bBoxUnits ? 1 : this.getViewport(), bBoxUnits ? 0.5 : 0.5 * this.getViewport());
3184
+ x1 = this.getLength('fx', bBoxUnits ? 1 : this.getVWidth(), x2);
3185
+ y1 = this.getLength('fy', bBoxUnits ? 1 : this.getVHeight(), y2);
3186
+
3187
+ if (r2 < 0) {
3188
+ warningCallback('SvgElemGradient: negative r value');
3189
+ }
3190
+
3191
+ let d = Math.sqrt(Math.pow(x2 - x1, 2) + Math.pow(y2 - y1, 2)),
3192
+ multiplier = 1;
3193
+
3194
+ if (d > r2) {
3195
+ // according to specification
3196
+ multiplier = r2 / d;
3197
+ x1 = x2 + (x1 - x2) * multiplier;
3198
+ y1 = y2 + (y1 - y2) * multiplier;
3199
+ }
3200
+
3201
+ r2 = Math.max(r2, d * multiplier * (1 + 1e-6)); // fix for edge-case gradients see issue #84
3202
+ }
3203
+
3204
+ if (spread === 'reflect' || spread === 'repeat') {
3205
+ let inv = inverseMatrix(matrix),
3206
+ corner1 = transformPoint([bBox[0], bBox[1]], inv),
3207
+ corner2 = transformPoint([bBox[2], bBox[1]], inv),
3208
+ corner3 = transformPoint([bBox[2], bBox[3]], inv),
3209
+ corner4 = transformPoint([bBox[0], bBox[3]], inv);
3210
+
3211
+ if (this.name === 'linearGradient') {
3212
+ // See file 'gradient-repeat-maths.png'
3213
+ 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));
3214
+ 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));
3215
+ } else {
3216
+ 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;
3217
+ }
3218
+
3219
+ nAfter = Math.ceil(nAfter + 0.5); // Add a little more because the stroke can extend outside of the bounding box
3220
+
3221
+ nBefore = Math.ceil(nBefore + 0.5);
3222
+ nTotal = nBefore + 1 + nAfter; // How many times the gradient needs to be repeated to fill the object bounding box
3223
+ }
3224
+
3225
+ if (this.name === 'linearGradient') {
3226
+ grad = doc.linearGradient(x1 - nBefore * (x2 - x1), y1 - nBefore * (y2 - y1), x2 + nAfter * (x2 - x1), y2 + nAfter * (y2 - y1));
3227
+ } else {
3228
+ grad = doc.radialGradient(x1, y1, 0, x2, y2, r2 + nAfter * r2);
3229
+ }
3230
+
3231
+ for (let n = 0; n < nTotal; n++) {
3232
+ let offset = 0,
3233
+ inOrder = spread !== 'reflect' || (n - nBefore) % 2 === 0;
3234
+
3235
+ for (let i = 0; i < children.length; i++) {
3236
+ let child = children[inOrder ? i : children.length - 1 - i],
3237
+ stopColor = child.get('stop-color');
3238
+
3239
+ if (stopColor === 'none') {
3240
+ stopColor = DefaultColors.transparent;
3241
+ }
3242
+
3243
+ stopColor = opacityToColor(stopColor, child.get('stop-opacity') * gOpacity, isMask);
3244
+ offset = Math.max(offset, inOrder ? child.getPercent('offset', 0) : 1 - child.getPercent('offset', 0));
3245
+
3246
+ if (i === 0 && stopColor[0].length === 4) {
3247
+ grad._colorSpace = 'DeviceCMYK';
3248
+ } // Fix until PR #763 is merged into PDFKit
3249
+
3250
+
3251
+ if (i === 0 && offset > 0) {
3252
+ grad.stop((n + 0) / nTotal, stopColor[0], stopColor[1]);
3253
+ }
3254
+
3255
+ grad.stop((n + offset) / (nAfter + nBefore + 1), stopColor[0], stopColor[1]);
3256
+
3257
+ if (i === children.length - 1 && offset < 1) {
3258
+ grad.stop((n + 1) / nTotal, stopColor[0], stopColor[1]);
3259
+ }
3260
+ }
3261
+ }
3262
+
3263
+ grad.setTransform.apply(grad, matrix);
3264
+ return [grad, 1];
3265
+ } else {
3266
+ return fallback ? [fallback[0], fallback[1] * gOpacity] : undefined;
3267
+ }
3268
+ };
3269
+ };
3270
+
3271
+ var SvgElemBasicShape = function (obj, inherits) {
3272
+ SvgElemStylable.call(this, obj, inherits);
3273
+ this.dashScale = 1;
3274
+
3275
+ this.getBoundingShape = function () {
3276
+ return this.shape;
3277
+ };
3278
+
3279
+ this.getTransformation = function () {
3280
+ return this.get('transform');
3281
+ };
3282
+
3283
+ this.drawInDocument = function (isClip, isMask) {
3284
+ if (this.get('visibility') === 'hidden' || !this.shape) {
3285
+ return;
3286
+ }
3287
+
3288
+ doc.save();
3289
+ this.transform();
3290
+ this.clip();
3291
+
3292
+ if (!isClip) {
3293
+ let masked = this.mask(),
3294
+ group;
3295
+
3296
+ if (masked) {
3297
+ group = docBeginGroup(getPageBBox());
3298
+ }
3299
+
3300
+ let subPaths = this.shape.getSubPaths(),
3301
+ fill = this.getFill(isClip, isMask),
3302
+ stroke = this.getStroke(isClip, isMask),
3303
+ lineWidth = this.get('stroke-width'),
3304
+ lineCap = this.get('stroke-linecap');
3305
+
3306
+ if (fill || stroke) {
3307
+ if (fill) {
3308
+ docFillColor(fill);
3309
+ }
3310
+
3311
+ if (stroke) {
3312
+ for (let j = 0; j < subPaths.length; j++) {
3313
+ if (isEqual(subPaths[j].totalLength, 0)) {
3314
+ if ((lineCap === 'square' || lineCap === 'round') && lineWidth > 0) {
3315
+ if (subPaths[j].startPoint && subPaths[j].startPoint.length > 1) {
3316
+ let x = subPaths[j].startPoint[0],
3317
+ y = subPaths[j].startPoint[1];
3318
+ docFillColor(stroke);
3319
+
3320
+ if (lineCap === 'square') {
3321
+ doc.rect(x - 0.5 * lineWidth, y - 0.5 * lineWidth, lineWidth, lineWidth);
3322
+ } else if (lineCap === 'round') {
3323
+ doc.circle(x, y, 0.5 * lineWidth);
3324
+ }
3325
+
3326
+ doc.fill();
3327
+ }
3328
+ }
3329
+ }
3330
+ }
3331
+
3332
+ let dashArray = this.get('stroke-dasharray'),
3333
+ dashOffset = this.get('stroke-dashoffset');
3334
+
3335
+ if (isNotEqual(this.dashScale, 1)) {
3336
+ for (let j = 0; j < dashArray.length; j++) {
3337
+ dashArray[j] *= this.dashScale;
3338
+ }
3339
+
3340
+ dashOffset *= this.dashScale;
3341
+ }
3342
+
3343
+ docStrokeColor(stroke);
3344
+ doc.lineWidth(lineWidth).miterLimit(this.get('stroke-miterlimit')).lineJoin(this.get('stroke-linejoin')).lineCap(lineCap).dash(dashArray, {
3345
+ phase: dashOffset
3346
+ });
3347
+ }
3348
+
3349
+ for (let j = 0; j < subPaths.length; j++) {
3350
+ if (subPaths[j].totalLength > 0) {
3351
+ subPaths[j].insertInDocument();
3352
+ }
3353
+ }
3354
+
3355
+ if (fill && stroke) {
3356
+ doc.fillAndStroke(this.get('fill-rule'));
3357
+ } else if (fill) {
3358
+ doc.fill(this.get('fill-rule'));
3359
+ } else if (stroke) {
3360
+ doc.stroke();
3361
+ }
3362
+ }
3363
+
3364
+ let markerStart = this.get('marker-start'),
3365
+ markerMid = this.get('marker-mid'),
3366
+ markerEnd = this.get('marker-end');
3367
+
3368
+ if (markerStart !== 'none' || markerMid !== 'none' || markerEnd !== 'none') {
3369
+ let markersPos = this.shape.getMarkers();
3370
+
3371
+ if (markerStart !== 'none') {
3372
+ let marker = new SvgElemMarker(markerStart, null);
3373
+ marker.drawMarker(false, isMask, markersPos[0], lineWidth);
3374
+ }
3375
+
3376
+ if (markerMid !== 'none') {
3377
+ for (let i = 1; i < markersPos.length - 1; i++) {
3378
+ let marker = new SvgElemMarker(markerMid, null);
3379
+ marker.drawMarker(false, isMask, markersPos[i], lineWidth);
3380
+ }
3381
+ }
3382
+
3383
+ if (markerEnd !== 'none') {
3384
+ let marker = new SvgElemMarker(markerEnd, null);
3385
+ marker.drawMarker(false, isMask, markersPos[markersPos.length - 1], lineWidth);
3386
+ }
3387
+ }
3388
+
3389
+ if (group) {
3390
+ docEndGroup(group);
3391
+ docInsertGroup(group);
3392
+ }
3393
+ } else {
3394
+ this.shape.insertInDocument();
3395
+ docFillColor(DefaultColors.white);
3396
+ doc.fill(this.get('clip-rule'));
3397
+ }
3398
+
3399
+ doc.restore();
3400
+ };
3401
+ };
3402
+
3403
+ var SvgElemRect = function (obj, inherits) {
3404
+ SvgElemBasicShape.call(this, obj, inherits);
3405
+ let x = this.getLength('x', this.getVWidth(), 0),
3406
+ y = this.getLength('y', this.getVHeight(), 0),
3407
+ w = this.getLength('width', this.getVWidth(), 0),
3408
+ h = this.getLength('height', this.getVHeight(), 0),
3409
+ rx = this.getLength('rx', this.getVWidth()),
3410
+ ry = this.getLength('ry', this.getVHeight());
3411
+
3412
+ if (rx === undefined && ry === undefined) {
3413
+ rx = ry = 0;
3414
+ } else if (rx === undefined && ry !== undefined) {
3415
+ rx = ry;
3416
+ } else if (rx !== undefined && ry === undefined) {
3417
+ ry = rx;
3418
+ }
3419
+
3420
+ if (w > 0 && h > 0) {
3421
+ if (rx && ry) {
3422
+ rx = Math.min(rx, 0.5 * w);
3423
+ ry = Math.min(ry, 0.5 * h);
3424
+ 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();
3425
+ } else {
3426
+ this.shape = new SvgShape().M(x, y).L(x + w, y).L(x + w, y + h).L(x, y + h).Z();
3427
+ }
3428
+ } else {
3429
+ this.shape = new SvgShape();
3430
+ }
3431
+ };
3432
+
3433
+ var SvgElemCircle = function (obj, inherits) {
3434
+ SvgElemBasicShape.call(this, obj, inherits);
3435
+ let cx = this.getLength('cx', this.getVWidth(), 0),
3436
+ cy = this.getLength('cy', this.getVHeight(), 0),
3437
+ r = this.getLength('r', this.getViewport(), 0);
3438
+
3439
+ if (r > 0) {
3440
+ 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();
3441
+ } else {
3442
+ this.shape = new SvgShape();
3443
+ }
3444
+ };
3445
+
3446
+ var SvgElemEllipse = function (obj, inherits) {
3447
+ SvgElemBasicShape.call(this, obj, inherits);
3448
+ let cx = this.getLength('cx', this.getVWidth(), 0),
3449
+ cy = this.getLength('cy', this.getVHeight(), 0),
3450
+ rx = this.getLength('rx', this.getVWidth(), 0),
3451
+ ry = this.getLength('ry', this.getVHeight(), 0);
3452
+
3453
+ if (rx > 0 && ry > 0) {
3454
+ 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();
3455
+ } else {
3456
+ this.shape = new SvgShape();
3457
+ }
3458
+ };
3459
+
3460
+ var SvgElemLine = function (obj, inherits) {
3461
+ SvgElemBasicShape.call(this, obj, inherits);
3462
+ let x1 = this.getLength('x1', this.getVWidth(), 0),
3463
+ y1 = this.getLength('y1', this.getVHeight(), 0),
3464
+ x2 = this.getLength('x2', this.getVWidth(), 0),
3465
+ y2 = this.getLength('y2', this.getVHeight(), 0);
3466
+ this.shape = new SvgShape().M(x1, y1).L(x2, y2);
3467
+ };
3468
+
3469
+ var SvgElemPolyline = function (obj, inherits) {
3470
+ SvgElemBasicShape.call(this, obj, inherits);
3471
+ let points = this.getNumberList('points');
3472
+ this.shape = new SvgShape();
3473
+
3474
+ for (let i = 0; i < points.length - 1; i += 2) {
3475
+ if (i === 0) {
3476
+ this.shape.M(points[i], points[i + 1]);
3477
+ } else {
3478
+ this.shape.L(points[i], points[i + 1]);
3479
+ }
3480
+ }
3481
+
3482
+ if (points.error) {
3483
+ warningCallback('SvgElemPolygon: unexpected string ' + points.error);
3484
+ }
3485
+
3486
+ if (points.length % 2 === 1) {
3487
+ warningCallback('SvgElemPolyline: uneven number of coordinates');
3488
+ }
3489
+ };
3490
+
3491
+ var SvgElemPolygon = function (obj, inherits) {
3492
+ SvgElemBasicShape.call(this, obj, inherits);
3493
+ let points = this.getNumberList('points');
3494
+ this.shape = new SvgShape();
3495
+
3496
+ for (let i = 0; i < points.length - 1; i += 2) {
3497
+ if (i === 0) {
3498
+ this.shape.M(points[i], points[i + 1]);
3499
+ } else {
3500
+ this.shape.L(points[i], points[i + 1]);
3501
+ }
3502
+ }
3503
+
3504
+ this.shape.Z();
3505
+
3506
+ if (points.error) {
3507
+ warningCallback('SvgElemPolygon: unexpected string ' + points.error);
3508
+ }
3509
+
3510
+ if (points.length % 2 === 1) {
3511
+ warningCallback('SvgElemPolygon: uneven number of coordinates');
3512
+ }
3513
+ };
3514
+
3515
+ var SvgElemPath = function (obj, inherits) {
3516
+ SvgElemBasicShape.call(this, obj, inherits);
3517
+ this.shape = new SvgShape().path(this.attr('d'));
3518
+ let pathLength = this.getLength('pathLength', this.getViewport());
3519
+ this.pathLength = pathLength > 0 ? pathLength : undefined;
3520
+ this.dashScale = this.pathLength !== undefined ? this.shape.totalLength / this.pathLength : 1;
3521
+ };
3522
+
3523
+ var SvgElemMarker = function (obj, inherits) {
3524
+ SvgElemHasChildren.call(this, obj, inherits);
3525
+ let width = this.getLength('markerWidth', this.getParentVWidth(), 3),
3526
+ height = this.getLength('markerHeight', this.getParentVHeight(), 3),
3527
+ viewBox = this.getViewbox('viewBox', [0, 0, width, height]);
3528
+
3529
+ this.getVWidth = function () {
3530
+ return viewBox[2];
3531
+ };
3532
+
3533
+ this.getVHeight = function () {
3534
+ return viewBox[3];
3535
+ };
3536
+
3537
+ this.drawMarker = function (isClip, isMask, posArray, strokeWidth) {
3538
+ doc.save();
3539
+ let orient = this.attr('orient'),
3540
+ units = this.attr('markerUnits'),
3541
+ rotate = orient === 'auto' ? posArray[2] : (parseFloat(orient) || 0) * Math.PI / 180,
3542
+ scale = units === 'userSpaceOnUse' ? 1 : strokeWidth;
3543
+ doc.transform(Math.cos(rotate) * scale, Math.sin(rotate) * scale, -Math.sin(rotate) * scale, Math.cos(rotate) * scale, posArray[0], posArray[1]);
3544
+ let refX = this.getLength('refX', this.getVWidth(), 0),
3545
+ refY = this.getLength('refY', this.getVHeight(), 0),
3546
+ aspectRatioMatrix = parseAspectRatio(this.attr('preserveAspectRatio'), width, height, viewBox[2], viewBox[3], 0.5);
3547
+
3548
+ if (this.get('overflow') === 'hidden') {
3549
+ 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();
3550
+ }
3551
+
3552
+ doc.transform.apply(doc, aspectRatioMatrix);
3553
+ doc.translate(-refX, -refY);
3554
+ let group;
3555
+
3556
+ if (this.get('opacity') < 1 && !isClip) {
3557
+ group = docBeginGroup(getPageBBox());
3558
+ }
3559
+
3560
+ this.drawChildren(isClip, isMask);
3561
+
3562
+ if (group) {
3563
+ docEndGroup(group);
3564
+ doc.fillOpacity(this.get('opacity'));
3565
+ docInsertGroup(group);
3566
+ }
3567
+
3568
+ doc.restore();
3569
+ };
3570
+ };
3571
+
3572
+ var SvgElemClipPath = function (obj, inherits) {
3573
+ SvgElemHasChildren.call(this, obj, inherits);
3574
+
3575
+ this.useMask = function (bBox) {
3576
+ let group = docBeginGroup(getPageBBox());
3577
+ doc.save();
3578
+
3579
+ if (this.attr('clipPathUnits') === 'objectBoundingBox') {
3580
+ doc.transform(bBox[2] - bBox[0], 0, 0, bBox[3] - bBox[1], bBox[0], bBox[1]);
3581
+ }
3582
+
3583
+ this.clip();
3584
+ this.drawChildren(true, false);
3585
+ doc.restore();
3586
+ docEndGroup(group);
3587
+ docApplyMask(group, true);
3588
+ };
3589
+ };
3590
+
3591
+ var SvgElemMask = function (obj, inherits) {
3592
+ SvgElemHasChildren.call(this, obj, inherits);
3593
+
3594
+ this.useMask = function (bBox) {
3595
+ let group = docBeginGroup(getPageBBox());
3596
+ doc.save();
3597
+ let x, y, w, h;
3598
+
3599
+ if (this.attr('maskUnits') === 'userSpaceOnUse') {
3600
+ x = this.getLength('x', this.getVWidth(), -0.1 * (bBox[2] - bBox[0]) + bBox[0]);
3601
+ y = this.getLength('y', this.getVHeight(), -0.1 * (bBox[3] - bBox[1]) + bBox[1]);
3602
+ w = this.getLength('width', this.getVWidth(), 1.2 * (bBox[2] - bBox[0]));
3603
+ h = this.getLength('height', this.getVHeight(), 1.2 * (bBox[3] - bBox[1]));
3604
+ } else {
3605
+ x = this.getLength('x', this.getVWidth(), -0.1) * (bBox[2] - bBox[0]) + bBox[0];
3606
+ y = this.getLength('y', this.getVHeight(), -0.1) * (bBox[3] - bBox[1]) + bBox[1];
3607
+ w = this.getLength('width', this.getVWidth(), 1.2) * (bBox[2] - bBox[0]);
3608
+ h = this.getLength('height', this.getVHeight(), 1.2) * (bBox[3] - bBox[1]);
3609
+ }
3610
+
3611
+ doc.rect(x, y, w, h).clip();
3612
+
3613
+ if (this.attr('maskContentUnits') === 'objectBoundingBox') {
3614
+ doc.transform(bBox[2] - bBox[0], 0, 0, bBox[3] - bBox[1], bBox[0], bBox[1]);
3615
+ }
3616
+
3617
+ this.clip();
3618
+ this.drawChildren(false, true);
3619
+ doc.restore();
3620
+ docEndGroup(group);
3621
+ docApplyMask(group, true);
3622
+ };
3623
+ };
3624
+
3625
+ var SvgElemTextContainer = function (obj, inherits) {
3626
+ SvgElemStylable.call(this, obj, inherits);
3627
+ this.allowedChildren = ['tspan', '#text', '#cdata-section', 'a'];
3628
+ this.isText = true;
3629
+
3630
+ this.getBoundingShape = function () {
3631
+ let shape = new SvgShape();
3632
+
3633
+ for (let i = 0; i < this._pos.length; i++) {
3634
+ let pos = this._pos[i];
3635
+
3636
+ if (!pos.hidden) {
3637
+ let dx0 = pos.ascent * Math.sin(pos.rotate),
3638
+ dy0 = -pos.ascent * Math.cos(pos.rotate),
3639
+ dx1 = pos.descent * Math.sin(pos.rotate),
3640
+ dy1 = -pos.descent * Math.cos(pos.rotate),
3641
+ dx2 = pos.width * Math.cos(pos.rotate),
3642
+ dy2 = pos.width * Math.sin(pos.rotate);
3643
+ 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);
3644
+ }
3645
+ }
3646
+
3647
+ return shape;
3648
+ };
3649
+
3650
+ this.drawTextInDocument = function (isClip, isMask) {
3651
+ if (this.link && !isClip && !isMask) {
3652
+ this.addLink();
3653
+ }
3654
+
3655
+ if (this.get('text-decoration') === 'underline') {
3656
+ this.decorate(0.05 * this._font.size, -0.075 * this._font.size, isClip, isMask);
3657
+ }
3658
+
3659
+ if (this.get('text-decoration') === 'overline') {
3660
+ this.decorate(0.05 * this._font.size, getAscent(this._font.font, this._font.size) + 0.075 * this._font.size, isClip, isMask);
3661
+ }
3662
+
3663
+ let fill = this.getFill(isClip, isMask),
3664
+ stroke = this.getStroke(isClip, isMask),
3665
+ strokeWidth = this.get('stroke-width');
3666
+
3667
+ if (this._font.fauxBold) {
3668
+ if (!stroke) {
3669
+ stroke = fill;
3670
+ strokeWidth = this._font.size * 0.03;
3671
+ } else {
3672
+ strokeWidth += this._font.size * 0.03;
3673
+ }
3674
+ }
3675
+
3676
+ let children = this.getChildren();
3677
+
3678
+ for (let i = 0; i < children.length; i++) {
3679
+ let childElem = children[i];
3680
+
3681
+ switch (childElem.name) {
3682
+ case 'tspan':
3683
+ case 'textPath':
3684
+ case 'a':
3685
+ if (childElem.get('display') !== 'none') {
3686
+ childElem.drawTextInDocument(isClip, isMask);
3687
+ }
3688
+
3689
+ break;
3690
+
3691
+ case '#text':
3692
+ case '#cdata-section':
3693
+ if (this.get('visibility') === 'hidden') {
3694
+ continue;
3695
+ }
3696
+
3697
+ if (fill || stroke || isClip) {
3698
+ if (fill) {
3699
+ docFillColor(fill);
3700
+ }
3701
+
3702
+ if (stroke && strokeWidth) {
3703
+ docStrokeColor(stroke);
3704
+ doc.lineWidth(strokeWidth).miterLimit(this.get('stroke-miterlimit')).lineJoin(this.get('stroke-linejoin')).lineCap(this.get('stroke-linecap')).dash(this.get('stroke-dasharray'), {
3705
+ phase: this.get('stroke-dashoffset')
3706
+ });
3707
+ }
3708
+
3709
+ docBeginText(this._font.font, this._font.size);
3710
+ docSetTextMode(!!fill, !!stroke);
3711
+
3712
+ for (let j = 0, pos = childElem._pos; j < pos.length; j++) {
3713
+ if (!pos[j].hidden && isNotEqual(pos[j].width, 0)) {
3714
+ let cos = Math.cos(pos[j].rotate),
3715
+ sin = Math.sin(pos[j].rotate),
3716
+ skew = this._font.fauxItalic ? -0.25 : 0;
3717
+ docSetTextMatrix(cos * pos[j].scale, sin * pos[j].scale, cos * skew - sin, sin * skew + cos, pos[j].x, pos[j].y);
3718
+ docWriteGlyph(pos[j].glyph);
3719
+ }
3720
+ }
3721
+
3722
+ docEndText();
3723
+ }
3724
+
3725
+ break;
3726
+ }
3727
+ }
3728
+
3729
+ if (this.get('text-decoration') === 'line-through') {
3730
+ 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);
3731
+ }
3732
+ };
3733
+
3734
+ this.decorate = function (lineWidth, linePosition, isClip, isMask) {
3735
+ let fill = this.getFill(isClip, isMask),
3736
+ stroke = this.getStroke(isClip, isMask);
3737
+
3738
+ if (fill) {
3739
+ docFillColor(fill);
3740
+ }
3741
+
3742
+ if (stroke) {
3743
+ docStrokeColor(stroke);
3744
+ 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'), {
3745
+ phase: this.get('stroke-dashoffset')
3746
+ });
3747
+ }
3748
+
3749
+ for (let j = 0, pos = this._pos; j < pos.length; j++) {
3750
+ if (!pos[j].hidden && isNotEqual(pos[j].width, 0)) {
3751
+ let dx0 = (linePosition + lineWidth / 2) * Math.sin(pos[j].rotate),
3752
+ dy0 = -(linePosition + lineWidth / 2) * Math.cos(pos[j].rotate),
3753
+ dx1 = (linePosition - lineWidth / 2) * Math.sin(pos[j].rotate),
3754
+ dy1 = -(linePosition - lineWidth / 2) * Math.cos(pos[j].rotate),
3755
+ dx2 = pos[j].width * Math.cos(pos[j].rotate),
3756
+ dy2 = pos[j].width * Math.sin(pos[j].rotate);
3757
+ 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();
3758
+
3759
+ if (fill && stroke) {
3760
+ doc.fillAndStroke();
3761
+ } else if (fill) {
3762
+ doc.fill();
3763
+ } else if (stroke) {
3764
+ doc.stroke();
3765
+ }
3766
+ }
3767
+ }
3768
+ };
3769
+ };
3770
+
3771
+ var SvgElemTextNode = function (obj, inherits) {
3772
+ this.name = obj.nodeName;
3773
+ this.textContent = obj.nodeValue;
3774
+ };
3775
+
3776
+ var SvgElemTspan = function (obj, inherits) {
3777
+ SvgElemTextContainer.call(this, obj, inherits);
3778
+ };
3779
+
3780
+ var SvgElemTextPath = function (obj, inherits) {
3781
+ SvgElemTextContainer.call(this, obj, inherits);
3782
+ let pathObject, pathLength, temp;
3783
+
3784
+ if ((temp = this.attr('path')) && temp.trim() !== '') {
3785
+ let pathLength = this.getLength('pathLength', this.getViewport());
3786
+ this.pathObject = new SvgShape().path(temp);
3787
+ this.pathLength = pathLength > 0 ? pathLength : this.pathObject.totalLength;
3788
+ this.pathScale = this.pathObject.totalLength / this.pathLength;
3789
+ } else if ((temp = this.getUrl('href') || this.getUrl('xlink:href')) && temp.nodeName === 'path') {
3790
+ let pathElem = new SvgElemPath(temp, this);
3791
+ this.pathObject = pathElem.shape.clone().transform(pathElem.get('transform'));
3792
+ this.pathLength = this.chooseValue(pathElem.pathLength, this.pathObject.totalLength);
3793
+ this.pathScale = this.pathObject.totalLength / this.pathLength;
3794
+ }
3795
+ };
3796
+
3797
+ var SvgElemText = function (obj, inherits) {
3798
+ SvgElemTextContainer.call(this, obj, inherits);
3799
+ this.allowedChildren = ['textPath', 'tspan', '#text', '#cdata-section', 'a'];
3800
+
3801
+ (function (textParentElem) {
3802
+ let processedText = '',
3803
+ remainingText = obj.textContent,
3804
+ textPaths = [],
3805
+ currentChunk = [],
3806
+ currentAnchor,
3807
+ currentDirection,
3808
+ currentX = 0,
3809
+ currentY = 0;
3810
+
3811
+ function doAnchoring() {
3812
+ if (currentChunk.length) {
3813
+ let last = currentChunk[currentChunk.length - 1];
3814
+ let first = currentChunk[0];
3815
+ let width = last.x + last.width - first.x;
3816
+ let anchordx = {
3817
+ 'startltr': 0,
3818
+ 'middleltr': 0.5,
3819
+ 'endltr': 1,
3820
+ 'startrtl': 1,
3821
+ 'middlertl': 0.5,
3822
+ 'endrtl': 0
3823
+ }[currentAnchor + currentDirection] * width || 0;
3824
+
3825
+ for (let i = 0; i < currentChunk.length; i++) {
3826
+ currentChunk[i].x -= anchordx;
3827
+ }
3828
+ }
3829
+
3830
+ currentChunk = [];
3831
+ }
3832
+
3833
+ function adjustLength(pos, length, spacingAndGlyphs) {
3834
+ let firstChar = pos[0],
3835
+ lastChar = pos[pos.length - 1],
3836
+ startX = firstChar.x,
3837
+ endX = lastChar.x + lastChar.width;
3838
+
3839
+ if (spacingAndGlyphs) {
3840
+ let textScale = length / (endX - startX);
3841
+
3842
+ if (textScale > 0 && textScale < Infinity) {
3843
+ for (let j = 0; j < pos.length; j++) {
3844
+ pos[j].x = startX + textScale * (pos[j].x - startX);
3845
+ pos[j].scale *= textScale;
3846
+ pos[j].width *= textScale;
3847
+ }
3848
+ }
3849
+ } else {
3850
+ if (pos.length >= 2) {
3851
+ let spaceDiff = (length - (endX - startX)) / (pos.length - 1);
3852
+
3853
+ for (let j = 0; j < pos.length; j++) {
3854
+ pos[j].x += j * spaceDiff;
3855
+ }
3856
+ }
3857
+ }
3858
+
3859
+ currentX += length - (endX - startX);
3860
+ }
3861
+
3862
+ function recursive(currentElem, parentElem) {
3863
+ currentElem._x = combineArrays(currentElem.getLengthList('x', currentElem.getVWidth()), parentElem ? parentElem._x.slice(parentElem._pos.length) : []);
3864
+ currentElem._y = combineArrays(currentElem.getLengthList('y', currentElem.getVHeight()), parentElem ? parentElem._y.slice(parentElem._pos.length) : []);
3865
+ currentElem._dx = combineArrays(currentElem.getLengthList('dx', currentElem.getVWidth()), parentElem ? parentElem._dx.slice(parentElem._pos.length) : []);
3866
+ currentElem._dy = combineArrays(currentElem.getLengthList('dy', currentElem.getVHeight()), parentElem ? parentElem._dy.slice(parentElem._pos.length) : []);
3867
+ currentElem._rot = combineArrays(currentElem.getNumberList('rotate'), parentElem ? parentElem._rot.slice(parentElem._pos.length) : []);
3868
+ currentElem._defRot = currentElem.chooseValue(currentElem._rot[currentElem._rot.length - 1], parentElem && parentElem._defRot, 0);
3869
+
3870
+ if (currentElem.name === 'textPath') {
3871
+ currentElem._y = [];
3872
+ }
3873
+
3874
+ let fontOptions = {
3875
+ fauxItalic: false,
3876
+ fauxBold: false
3877
+ },
3878
+ fontNameorLink = fontCallback(currentElem.get('font-family'), currentElem.get('font-weight') === 'bold', currentElem.get('font-style') === 'italic', fontOptions);
3879
+
3880
+ try {
3881
+ doc.font(fontNameorLink);
3882
+ } catch (e) {
3883
+ warningCallback('SVGElemText: failed to open font "' + fontNameorLink + '" in PDFKit');
3884
+ }
3885
+
3886
+ currentElem._pos = [];
3887
+ currentElem._index = 0;
3888
+ currentElem._font = {
3889
+ font: doc._font,
3890
+ size: currentElem.get('font-size'),
3891
+ fauxItalic: fontOptions.fauxItalic,
3892
+ fauxBold: fontOptions.fauxBold
3893
+ };
3894
+ let textLength = currentElem.getLength('textLength', currentElem.getVWidth(), undefined),
3895
+ spacingAndGlyphs = currentElem.attr('lengthAdjust') === 'spacingAndGlyphs',
3896
+ wordSpacing = currentElem.get('word-spacing'),
3897
+ letterSpacing = currentElem.get('letter-spacing'),
3898
+ textAnchor = currentElem.get('text-anchor'),
3899
+ textDirection = currentElem.get('direction'),
3900
+ baseline = getBaseline(currentElem._font.font, currentElem._font.size, currentElem.get('alignment-baseline') || currentElem.get('dominant-baseline'), currentElem.get('baseline-shift'));
3901
+
3902
+ if (currentElem.name === 'textPath') {
3903
+ doAnchoring();
3904
+ currentX = currentY = 0;
3905
+ }
3906
+
3907
+ let children = currentElem.getChildren();
3908
+
3909
+ for (let i = 0; i < children.length; i++) {
3910
+ let childElem = children[i];
3911
+
3912
+ switch (childElem.name) {
3913
+ case 'tspan':
3914
+ case 'textPath':
3915
+ case 'a':
3916
+ recursive(childElem, currentElem);
3917
+ break;
3918
+
3919
+ case '#text':
3920
+ case '#cdata-section':
3921
+ let rawText = childElem.textContent,
3922
+ renderedText = rawText,
3923
+ words;
3924
+ childElem._font = currentElem._font;
3925
+ childElem._pos = [];
3926
+ remainingText = remainingText.substring(rawText.length);
3927
+
3928
+ if (currentElem.get('xml:space') === 'preserve') {
3929
+ renderedText = renderedText.replace(/[\s]/g, ' ');
3930
+ } else {
3931
+ renderedText = renderedText.replace(/[\s]+/g, ' ');
3932
+
3933
+ if (processedText.match(/[\s]$|^$/)) {
3934
+ renderedText = renderedText.replace(/^[\s]/, '');
3935
+ }
3936
+
3937
+ if (remainingText.match(/^[\s]*$/)) {
3938
+ renderedText = renderedText.replace(/[\s]$/, '');
3939
+ }
3940
+ }
3941
+
3942
+ processedText += rawText;
3943
+
3944
+ if (wordSpacing === 0) {
3945
+ words = [renderedText];
3946
+ } else {
3947
+ words = renderedText.split(/(\s)/);
3948
+ }
3949
+
3950
+ for (let w = 0; w < words.length; w++) {
3951
+ let pos = getTextPos(currentElem._font.font, currentElem._font.size, words[w]);
3952
+
3953
+ for (let j = 0; j < pos.length; j++) {
3954
+ let index = currentElem._index,
3955
+ xAttr = currentElem._x[index],
3956
+ yAttr = currentElem._y[index],
3957
+ dxAttr = currentElem._dx[index],
3958
+ dyAttr = currentElem._dy[index],
3959
+ rotAttr = currentElem._rot[index],
3960
+ continuous = !(w === 0 && j === 0);
3961
+
3962
+ if (xAttr !== undefined) {
3963
+ continuous = false;
3964
+ doAnchoring();
3965
+ currentX = xAttr;
3966
+ }
3967
+
3968
+ if (yAttr !== undefined) {
3969
+ continuous = false;
3970
+ doAnchoring();
3971
+ currentY = yAttr;
3972
+ }
3973
+
3974
+ if (dxAttr !== undefined) {
3975
+ continuous = false;
3976
+ currentX += dxAttr;
3977
+ }
3978
+
3979
+ if (dyAttr !== undefined) {
3980
+ continuous = false;
3981
+ currentY += dyAttr;
3982
+ }
3983
+
3984
+ if (rotAttr !== undefined || currentElem._defRot !== 0) {
3985
+ continuous = false;
3986
+ }
3987
+
3988
+ let position = {
3989
+ glyph: pos[j].glyph,
3990
+ rotate: Math.PI / 180 * currentElem.chooseValue(rotAttr, currentElem._defRot),
3991
+ x: currentX + pos[j].xOffset,
3992
+ y: currentY + baseline + pos[j].yOffset,
3993
+ width: pos[j].width,
3994
+ ascent: getAscent(currentElem._font.font, currentElem._font.size),
3995
+ descent: getDescent(currentElem._font.font, currentElem._font.size),
3996
+ scale: 1,
3997
+ hidden: false,
3998
+ continuous: continuous
3999
+ };
4000
+ currentChunk.push(position);
4001
+
4002
+ childElem._pos.push(position);
4003
+
4004
+ currentElem._pos.push(position);
4005
+
4006
+ currentElem._index += pos[j].unicode.length;
4007
+
4008
+ if (currentChunk.length === 1) {
4009
+ currentAnchor = textAnchor;
4010
+ currentDirection = textDirection;
4011
+ }
4012
+
4013
+ currentX += pos[j].xAdvance + letterSpacing;
4014
+ currentY += pos[j].yAdvance;
4015
+ }
4016
+
4017
+ if (words[w] === ' ') {
4018
+ currentX += wordSpacing;
4019
+ }
4020
+ }
4021
+
4022
+ break;
4023
+
4024
+ default:
4025
+ remainingText = remainingText.substring(childElem.textContent.length);
4026
+ }
4027
+ }
4028
+
4029
+ if (textLength && currentElem._pos.length) {
4030
+ adjustLength(currentElem._pos, textLength, spacingAndGlyphs);
4031
+ }
4032
+
4033
+ if (currentElem.name === 'textPath' || currentElem.name === 'text') {
4034
+ doAnchoring();
4035
+ }
4036
+
4037
+ if (currentElem.name === 'textPath') {
4038
+ textPaths.push(currentElem);
4039
+ let pathObject = currentElem.pathObject;
4040
+
4041
+ if (pathObject) {
4042
+ currentX = pathObject.endPoint[0];
4043
+ currentY = pathObject.endPoint[1];
4044
+ }
4045
+ }
4046
+
4047
+ if (parentElem) {
4048
+ parentElem._pos = parentElem._pos.concat(currentElem._pos);
4049
+ parentElem._index += currentElem._index;
4050
+ }
4051
+ }
4052
+
4053
+ function textOnPath(currentElem) {
4054
+ let pathObject = currentElem.pathObject,
4055
+ pathLength = currentElem.pathLength,
4056
+ pathScale = currentElem.pathScale;
4057
+
4058
+ if (pathObject) {
4059
+ let textOffset = currentElem.getLength('startOffset', pathLength, 0);
4060
+
4061
+ for (let j = 0; j < currentElem._pos.length; j++) {
4062
+ let charMidX = textOffset + currentElem._pos[j].x + 0.5 * currentElem._pos[j].width;
4063
+
4064
+ if (charMidX > pathLength || charMidX < 0) {
4065
+ currentElem._pos[j].hidden = true;
4066
+ } else {
4067
+ let pointOnPath = pathObject.getPointAtLength(charMidX * pathScale);
4068
+
4069
+ if (isNotEqual(pathScale, 1)) {
4070
+ currentElem._pos[j].scale *= pathScale;
4071
+ currentElem._pos[j].width *= pathScale;
4072
+ }
4073
+
4074
+ currentElem._pos[j].x = pointOnPath[0] - 0.5 * currentElem._pos[j].width * Math.cos(pointOnPath[2]) - currentElem._pos[j].y * Math.sin(pointOnPath[2]);
4075
+ currentElem._pos[j].y = pointOnPath[1] - 0.5 * currentElem._pos[j].width * Math.sin(pointOnPath[2]) + currentElem._pos[j].y * Math.cos(pointOnPath[2]);
4076
+ currentElem._pos[j].rotate = pointOnPath[2] + currentElem._pos[j].rotate;
4077
+ currentElem._pos[j].continuous = false;
4078
+ }
4079
+ }
4080
+ } else {
4081
+ for (let j = 0; j < currentElem._pos.length; j++) {
4082
+ currentElem._pos[j].hidden = true;
4083
+ }
4084
+ }
4085
+ }
4086
+
4087
+ recursive(textParentElem, null);
4088
+
4089
+ for (let i = 0; i < textPaths.length; i++) {
4090
+ textOnPath(textPaths[i]);
4091
+ }
4092
+ })(this);
4093
+
4094
+ this.getTransformation = function () {
4095
+ return this.get('transform');
4096
+ };
4097
+
4098
+ this.drawInDocument = function (isClip, isMask) {
4099
+ doc.save();
4100
+ this.transform();
4101
+ this.clip();
4102
+ let masked = this.mask(),
4103
+ group;
4104
+
4105
+ if (masked) {
4106
+ group = docBeginGroup(getPageBBox());
4107
+ }
4108
+
4109
+ this.drawTextInDocument(isClip, isMask);
4110
+
4111
+ if (group) {
4112
+ docEndGroup(group);
4113
+ docInsertGroup(group);
4114
+ }
4115
+
4116
+ doc.restore();
4117
+ };
4118
+ };
4119
+
4120
+ options = options || {};
4121
+ var pxToPt = options.assumePt ? 1 : 72 / 96,
4122
+ // 1px = 72/96pt, but only if assumePt is false
4123
+ viewportWidth = (options.width || doc.page.width) / pxToPt,
4124
+ viewportHeight = (options.height || doc.page.height) / pxToPt,
4125
+ preserveAspectRatio = options.preserveAspectRatio || null,
4126
+ // default to null so that the attr can override if not passed
4127
+ useCSS = options.useCSS && typeof SVGElement !== 'undefined' && svg instanceof SVGElement && typeof getComputedStyle === 'function',
4128
+ warningCallback = options.warningCallback,
4129
+ fontCallback = options.fontCallback,
4130
+ imageCallback = options.imageCallback,
4131
+ colorCallback = options.colorCallback,
4132
+ documentCallback = options.documentCallback,
4133
+ precision = Math.ceil(Math.max(1, options.precision)) || 3,
4134
+ groupStack = [],
4135
+ documentCache = {},
4136
+ links = [],
4137
+ styleRules = [];
4138
+
4139
+ if (typeof warningCallback !== 'function') {
4140
+ warningCallback = function (str) {
4141
+ if (typeof console !== undefined && typeof console.warn === 'function') {
4142
+ console.warn(str);
4143
+ }
4144
+ };
4145
+ }
4146
+
4147
+ if (typeof fontCallback !== 'function') {
4148
+ fontCallback = function (family, bold, italic, fontOptions) {
4149
+ // Check if the font is already registered in the document
4150
+ if (bold && italic) {
4151
+ if (doc._registeredFonts.hasOwnProperty(family + '-BoldItalic')) {
4152
+ return family + '-BoldItalic';
4153
+ } else if (doc._registeredFonts.hasOwnProperty(family + '-Italic')) {
4154
+ fontOptions.fauxBold = true;
4155
+ return family + '-Italic';
4156
+ } else if (doc._registeredFonts.hasOwnProperty(family + '-Bold')) {
4157
+ fontOptions.fauxItalic = true;
4158
+ return family + '-Bold';
4159
+ } else if (doc._registeredFonts.hasOwnProperty(family)) {
4160
+ fontOptions.fauxBold = true;
4161
+ fontOptions.fauxItalic = true;
4162
+ return family;
4163
+ }
4164
+ }
4165
+
4166
+ if (bold && !italic) {
4167
+ if (doc._registeredFonts.hasOwnProperty(family + '-Bold')) {
4168
+ return family + '-Bold';
4169
+ } else if (doc._registeredFonts.hasOwnProperty(family)) {
4170
+ fontOptions.fauxBold = true;
4171
+ return family;
4172
+ }
4173
+ }
4174
+
4175
+ if (!bold && italic) {
4176
+ if (doc._registeredFonts.hasOwnProperty(family + '-Italic')) {
4177
+ return family + '-Italic';
4178
+ } else if (doc._registeredFonts.hasOwnProperty(family)) {
4179
+ fontOptions.fauxItalic = true;
4180
+ return family;
4181
+ }
4182
+ }
4183
+
4184
+ if (!bold && !italic) {
4185
+ if (doc._registeredFonts.hasOwnProperty(family)) {
4186
+ return family;
4187
+ }
4188
+ } // Use standard fonts as fallback
4189
+
4190
+
4191
+ if (family.match(/(?:^|,)\s*serif\s*$/)) {
4192
+ if (bold && italic) {
4193
+ return 'Times-BoldItalic';
4194
+ }
4195
+
4196
+ if (bold && !italic) {
4197
+ return 'Times-Bold';
4198
+ }
4199
+
4200
+ if (!bold && italic) {
4201
+ return 'Times-Italic';
4202
+ }
4203
+
4204
+ if (!bold && !italic) {
4205
+ return 'Times-Roman';
4206
+ }
4207
+ } else if (family.match(/(?:^|,)\s*monospace\s*$/)) {
4208
+ if (bold && italic) {
4209
+ return 'Courier-BoldOblique';
4210
+ }
4211
+
4212
+ if (bold && !italic) {
4213
+ return 'Courier-Bold';
4214
+ }
4215
+
4216
+ if (!bold && italic) {
4217
+ return 'Courier-Oblique';
4218
+ }
4219
+
4220
+ if (!bold && !italic) {
4221
+ return 'Courier';
4222
+ }
4223
+ } else if (family.match(/(?:^|,)\s*sans-serif\s*$/) || true) {
4224
+ if (bold && italic) {
4225
+ return 'Helvetica-BoldOblique';
4226
+ }
4227
+
4228
+ if (bold && !italic) {
4229
+ return 'Helvetica-Bold';
4230
+ }
4231
+
4232
+ if (!bold && italic) {
4233
+ return 'Helvetica-Oblique';
4234
+ }
4235
+
4236
+ if (!bold && !italic) {
4237
+ return 'Helvetica';
4238
+ }
4239
+ }
4240
+ };
4241
+ }
4242
+
4243
+ if (typeof imageCallback !== 'function') {
4244
+ imageCallback = function (link) {
4245
+ return link.replace(/\s+/g, '');
4246
+ };
4247
+ }
4248
+
4249
+ if (typeof colorCallback !== 'function') {
4250
+ colorCallback = null;
4251
+ } else {
4252
+ for (let color in DefaultColors) {
4253
+ let newColor = colorCallback(DefaultColors[color]);
4254
+ DefaultColors[color][0] = newColor[0];
4255
+ DefaultColors[color][1] = newColor[1];
4256
+ }
4257
+ }
4258
+
4259
+ if (typeof documentCallback !== 'function') {
4260
+ documentCallback = null;
4261
+ }
4262
+
4263
+ if (typeof svg === 'string') {
4264
+ svg = parseXml(svg);
4265
+ }
4266
+
4267
+ if (svg) {
4268
+ let styles = svg.getElementsByTagName('style');
4269
+
4270
+ for (let i = 0; i < styles.length; i++) {
4271
+ styleRules = styleRules.concat(parseStyleSheet(styles[i].textContent));
4272
+ }
4273
+
4274
+ let elem = createSVGElement(svg, null);
4275
+
4276
+ if (typeof elem.drawInDocument === 'function') {
4277
+ if (options.useCSS && !useCSS) {
4278
+ warningCallback('SVGtoPDF: useCSS option can only be used for SVG *elements* in compatible browsers');
4279
+ }
4280
+
4281
+ let savedFillColor = doc._fillColor;
4282
+ doc.save().translate(x || 0, y || 0).scale(pxToPt);
4283
+ elem.drawInDocument();
4284
+
4285
+ for (let i = 0; i < links.length; i++) {
4286
+ doc.page.annotations.push(links[i]);
4287
+ }
4288
+
4289
+ doc.restore();
4290
+ doc._fillColor = savedFillColor;
4291
+ } else {
4292
+ warningCallback('SVGtoPDF: this element can\'t be rendered directly: ' + svg.nodeName);
4293
+ }
4294
+ } else {
4295
+ warningCallback('SVGtoPDF: the input does not look like a valid SVG');
4296
+ }
4297
+ };
4298
+
4299
+ if (typeof module !== 'undefined' && module && typeof module.exports !== 'undefined') {
4300
+ module.exports = SVGtoPDF;
4301
+ }