@kittl/pdfkit 0.17.4 → 0.17.51

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