pdfmake 0.2.4 → 0.3.0-beta.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (128) hide show
  1. package/CHANGELOG.md +10 -27
  2. package/README.md +11 -7
  3. package/build/pdfmake.js +44733 -42435
  4. package/build/pdfmake.js.map +1 -1
  5. package/build/pdfmake.min.js +2 -2
  6. package/build/pdfmake.min.js.map +1 -1
  7. package/build/standard-fonts/Courier.js +27 -0
  8. package/build/standard-fonts/Helvetica.js +27 -0
  9. package/build/standard-fonts/Symbol.js +21 -0
  10. package/build/standard-fonts/Times.js +27 -0
  11. package/build/standard-fonts/ZapfDingbats.js +21 -0
  12. package/build/vfs_fonts.js +2 -2
  13. package/build-vfs.js +2 -2
  14. package/fonts/Roboto/Roboto-Italic.ttf +0 -0
  15. package/fonts/Roboto/Roboto-Medium.ttf +0 -0
  16. package/fonts/Roboto/Roboto-MediumItalic.ttf +0 -0
  17. package/fonts/Roboto/Roboto-Regular.ttf +0 -0
  18. package/fonts/Roboto.js +8 -0
  19. package/js/3rd-party/svg-to-pdfkit/source.js +4301 -0
  20. package/js/3rd-party/svg-to-pdfkit.js +11 -0
  21. package/js/DocMeasure.js +758 -0
  22. package/js/DocPreprocessor.js +291 -0
  23. package/js/DocumentContext.js +306 -0
  24. package/js/ElementWriter.js +400 -0
  25. package/js/LayoutBuilder.js +840 -0
  26. package/js/Line.js +125 -0
  27. package/js/OutputDocument.js +86 -0
  28. package/js/OutputDocumentServer.js +34 -0
  29. package/js/PDFDocument.js +190 -0
  30. package/js/PageElementWriter.js +165 -0
  31. package/js/PageSize.js +88 -0
  32. package/js/Printer.js +300 -0
  33. package/js/Renderer.js +463 -0
  34. package/js/SVGMeasure.js +89 -0
  35. package/js/StyleContextStack.js +206 -0
  36. package/js/TableProcessor.js +590 -0
  37. package/js/TextBreaker.js +182 -0
  38. package/js/TextDecorator.js +181 -0
  39. package/js/TextInlines.js +248 -0
  40. package/js/URLResolver.js +82 -0
  41. package/js/base.js +69 -0
  42. package/js/browser-extensions/OutputDocumentBrowser.js +131 -0
  43. package/js/browser-extensions/URLBrowserResolver.js +94 -0
  44. package/js/browser-extensions/fonts/Roboto.js +42 -0
  45. package/js/browser-extensions/index.js +70 -0
  46. package/js/browser-extensions/pdfMake.js +17 -0
  47. package/js/browser-extensions/standard-fonts/Courier.js +42 -0
  48. package/js/browser-extensions/standard-fonts/Helvetica.js +42 -0
  49. package/js/browser-extensions/standard-fonts/Symbol.js +27 -0
  50. package/js/browser-extensions/standard-fonts/Times.js +42 -0
  51. package/js/browser-extensions/standard-fonts/ZapfDingbats.js +27 -0
  52. package/js/browser-extensions/virtual-fs-cjs.js +3 -0
  53. package/js/columnCalculator.js +142 -0
  54. package/js/helpers/node.js +122 -0
  55. package/js/helpers/tools.js +48 -0
  56. package/js/helpers/variableType.js +52 -0
  57. package/js/index.js +21 -0
  58. package/js/qrEnc.js +810 -0
  59. package/js/standardPageSizes.js +57 -0
  60. package/js/tableLayouts.js +127 -0
  61. package/js/virtual-fs.js +77 -0
  62. package/package.json +26 -22
  63. package/src/3rd-party/svg-to-pdfkit.js +2 -2
  64. package/src/DocMeasure.js +703 -0
  65. package/src/DocPreprocessor.js +264 -0
  66. package/src/DocumentContext.js +309 -0
  67. package/src/ElementWriter.js +394 -0
  68. package/src/LayoutBuilder.js +821 -0
  69. package/src/Line.js +114 -0
  70. package/src/OutputDocument.js +78 -0
  71. package/src/OutputDocumentServer.js +26 -0
  72. package/src/PDFDocument.js +174 -0
  73. package/src/PageElementWriter.js +160 -0
  74. package/src/PageSize.js +53 -0
  75. package/src/Printer.js +277 -0
  76. package/src/Renderer.js +405 -0
  77. package/src/SVGMeasure.js +79 -0
  78. package/src/StyleContextStack.js +216 -0
  79. package/src/TableProcessor.js +558 -0
  80. package/src/TextBreaker.js +149 -0
  81. package/src/TextDecorator.js +161 -0
  82. package/src/TextInlines.js +223 -0
  83. package/src/URLResolver.js +72 -0
  84. package/src/base.js +61 -0
  85. package/src/browser-extensions/OutputDocumentBrowser.js +117 -0
  86. package/src/browser-extensions/URLBrowserResolver.js +49 -53
  87. package/src/browser-extensions/fonts/Roboto.js +27 -0
  88. package/src/browser-extensions/index.js +55 -0
  89. package/src/browser-extensions/pdfMake.js +10 -282
  90. package/src/browser-extensions/standard-fonts/Courier.js +27 -0
  91. package/src/browser-extensions/standard-fonts/Helvetica.js +27 -0
  92. package/src/browser-extensions/standard-fonts/Symbol.js +21 -0
  93. package/src/browser-extensions/standard-fonts/Times.js +27 -0
  94. package/src/browser-extensions/standard-fonts/ZapfDingbats.js +21 -0
  95. package/src/browser-extensions/virtual-fs-cjs.js +1 -0
  96. package/src/columnCalculator.js +29 -32
  97. package/src/helpers/node.js +110 -0
  98. package/src/helpers/tools.js +39 -0
  99. package/src/helpers/variableType.js +39 -0
  100. package/src/index.js +16 -0
  101. package/src/qrEnc.js +15 -10
  102. package/src/standardPageSizes.js +1 -3
  103. package/src/tableLayouts.js +100 -0
  104. package/src/virtual-fs.js +66 -0
  105. package/standard-fonts/Courier.js +8 -0
  106. package/standard-fonts/Helvetica.js +9 -0
  107. package/standard-fonts/Symbol.js +5 -0
  108. package/standard-fonts/Times.js +8 -0
  109. package/standard-fonts/ZapfDingbats.js +5 -0
  110. package/src/browser-extensions/virtual-fs.js +0 -55
  111. package/src/docMeasure.js +0 -807
  112. package/src/docPreprocessor.js +0 -255
  113. package/src/documentContext.js +0 -314
  114. package/src/elementWriter.js +0 -322
  115. package/src/fontProvider.js +0 -68
  116. package/src/helpers.js +0 -126
  117. package/src/imageMeasure.js +0 -51
  118. package/src/layoutBuilder.js +0 -807
  119. package/src/line.js +0 -91
  120. package/src/pageElementWriter.js +0 -174
  121. package/src/pdfKitEngine.js +0 -21
  122. package/src/printer.js +0 -705
  123. package/src/styleContextStack.js +0 -179
  124. package/src/svgMeasure.js +0 -70
  125. package/src/tableProcessor.js +0 -561
  126. package/src/textDecorator.js +0 -157
  127. package/src/textTools.js +0 -373
  128. package/src/traversalTracker.js +0 -47
package/js/Renderer.js ADDED
@@ -0,0 +1,463 @@
1
+ "use strict";
2
+
3
+ exports.__esModule = true;
4
+ exports.default = void 0;
5
+
6
+ var _TextDecorator = _interopRequireDefault(require("./TextDecorator"));
7
+
8
+ var _TextInlines = _interopRequireDefault(require("./TextInlines"));
9
+
10
+ var _variableType = require("./helpers/variableType");
11
+
12
+ var _svgToPdfkit = _interopRequireDefault(require("./3rd-party/svg-to-pdfkit"));
13
+
14
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
15
+
16
+ const findFont = (fonts, requiredFonts, defaultFont) => {
17
+ for (let i = 0; i < requiredFonts.length; i++) {
18
+ let requiredFont = requiredFonts[i].toLowerCase();
19
+
20
+ for (let font in fonts) {
21
+ if (font.toLowerCase() === requiredFont) {
22
+ return font;
23
+ }
24
+ }
25
+ }
26
+
27
+ return defaultFont;
28
+ };
29
+ /**
30
+ * Shift the "y" height of the text baseline up or down (superscript or subscript,
31
+ * respectively). The exact shift can / should be changed according to standard
32
+ * conventions.
33
+ *
34
+ * @param {number} y
35
+ * @param {object} inline
36
+ * @returns {number}
37
+ */
38
+
39
+
40
+ const offsetText = (y, inline) => {
41
+ var newY = y;
42
+
43
+ if (inline.sup) {
44
+ newY -= inline.fontSize * 0.75;
45
+ }
46
+
47
+ if (inline.sub) {
48
+ newY += inline.fontSize * 0.35;
49
+ }
50
+
51
+ return newY;
52
+ };
53
+
54
+ class Renderer {
55
+ constructor(pdfDocument, progressCallback) {
56
+ this.pdfDocument = pdfDocument;
57
+ this.progressCallback = progressCallback;
58
+ }
59
+
60
+ renderPages(pages) {
61
+ this.pdfDocument._pdfMakePages = pages; // TODO: Why?
62
+
63
+ this.pdfDocument.addPage();
64
+ let totalItems = 0;
65
+
66
+ if (this.progressCallback) {
67
+ pages.forEach(page => {
68
+ totalItems += page.items.length;
69
+ });
70
+ }
71
+
72
+ let renderedItems = 0;
73
+
74
+ for (let i = 0; i < pages.length; i++) {
75
+ if (i > 0) {
76
+ this._updatePageOrientationInOptions(pages[i]);
77
+
78
+ this.pdfDocument.addPage(this.pdfDocument.options);
79
+ }
80
+
81
+ let page = pages[i];
82
+
83
+ for (let ii = 0, il = page.items.length; ii < il; ii++) {
84
+ let item = page.items[ii];
85
+
86
+ switch (item.type) {
87
+ case 'vector':
88
+ this.renderVector(item.item);
89
+ break;
90
+
91
+ case 'line':
92
+ this.renderLine(item.item, item.item.x, item.item.y);
93
+ break;
94
+
95
+ case 'image':
96
+ this.renderImage(item.item);
97
+ break;
98
+
99
+ case 'svg':
100
+ this.renderSVG(item.item);
101
+ break;
102
+
103
+ case 'attachment':
104
+ this.renderAttachment(item.item);
105
+ break;
106
+
107
+ case 'beginClip':
108
+ this.beginClip(item.item);
109
+ break;
110
+
111
+ case 'endClip':
112
+ this.endClip();
113
+ break;
114
+ }
115
+
116
+ renderedItems++;
117
+
118
+ if (this.progressCallback) {
119
+ this.progressCallback(renderedItems / totalItems);
120
+ }
121
+ }
122
+
123
+ if (page.watermark) {
124
+ this.renderWatermark(page);
125
+ }
126
+ }
127
+ }
128
+
129
+ renderLine(line, x, y) {
130
+ function preparePageNodeRefLine(_pageNodeRef, inline) {
131
+ let newWidth;
132
+ let diffWidth;
133
+ let textInlines = new _TextInlines.default(null);
134
+
135
+ if (_pageNodeRef.positions === undefined) {
136
+ throw new Error('Page reference id not found');
137
+ }
138
+
139
+ let pageNumber = _pageNodeRef.positions[0].pageNumber.toString();
140
+
141
+ inline.text = pageNumber;
142
+ newWidth = textInlines.widthOfText(inline.text, inline);
143
+ diffWidth = inline.width - newWidth;
144
+ inline.width = newWidth;
145
+
146
+ switch (inline.alignment) {
147
+ case 'right':
148
+ inline.x += diffWidth;
149
+ break;
150
+
151
+ case 'center':
152
+ inline.x += diffWidth / 2;
153
+ break;
154
+ }
155
+ }
156
+
157
+ if (line._pageNodeRef) {
158
+ preparePageNodeRefLine(line._pageNodeRef, line.inlines[0]);
159
+ }
160
+
161
+ x = x || 0;
162
+ y = y || 0;
163
+ let lineHeight = line.getHeight();
164
+ let ascenderHeight = line.getAscenderHeight();
165
+ let descent = lineHeight - ascenderHeight;
166
+ const textDecorator = new _TextDecorator.default(this.pdfDocument);
167
+ textDecorator.drawBackground(line, x, y); //TODO: line.optimizeInlines();
168
+ //TOOD: lines without differently styled inlines should be written to pdf as one stream
169
+
170
+ for (let i = 0, l = line.inlines.length; i < l; i++) {
171
+ let inline = line.inlines[i];
172
+ let shiftToBaseline = lineHeight - inline.font.ascender / 1000 * inline.fontSize - descent;
173
+
174
+ if (inline._pageNodeRef) {
175
+ preparePageNodeRefLine(inline._pageNodeRef, inline);
176
+ }
177
+
178
+ let options = {
179
+ lineBreak: false,
180
+ textWidth: inline.width,
181
+ characterSpacing: inline.characterSpacing,
182
+ wordCount: 1,
183
+ link: inline.link
184
+ };
185
+
186
+ if (inline.linkToDestination) {
187
+ options.goTo = inline.linkToDestination;
188
+ }
189
+
190
+ if (line.id && i === 0) {
191
+ options.destination = line.id;
192
+ }
193
+
194
+ if (inline.fontFeatures) {
195
+ options.features = inline.fontFeatures;
196
+ }
197
+
198
+ let opacity = (0, _variableType.isNumber)(inline.opacity) ? inline.opacity : 1;
199
+ this.pdfDocument.opacity(opacity);
200
+ this.pdfDocument.fill(inline.color || 'black');
201
+ this.pdfDocument._font = inline.font;
202
+ this.pdfDocument.fontSize(inline.fontSize);
203
+ let shiftedY = offsetText(y + shiftToBaseline, inline);
204
+ this.pdfDocument.text(inline.text, x + inline.x, shiftedY, options);
205
+
206
+ if (inline.linkToPage) {
207
+ this.pdfDocument.ref({
208
+ Type: 'Action',
209
+ S: 'GoTo',
210
+ D: [inline.linkToPage, 0, 0]
211
+ }).end();
212
+ this.pdfDocument.annotate(x + inline.x, shiftedY, inline.width, inline.height, {
213
+ Subtype: 'Link',
214
+ Dest: [inline.linkToPage - 1, 'XYZ', null, null, null]
215
+ });
216
+ }
217
+ } // Decorations won't draw correctly for superscript
218
+
219
+
220
+ textDecorator.drawDecorations(line, x, y);
221
+ }
222
+
223
+ renderVector(vector) {
224
+ //TODO: pdf optimization (there's no need to write all properties everytime)
225
+ this.pdfDocument.lineWidth(vector.lineWidth || 1);
226
+
227
+ if (vector.dash) {
228
+ this.pdfDocument.dash(vector.dash.length, {
229
+ space: vector.dash.space || vector.dash.length,
230
+ phase: vector.dash.phase || 0
231
+ });
232
+ } else {
233
+ this.pdfDocument.undash();
234
+ }
235
+
236
+ this.pdfDocument.lineJoin(vector.lineJoin || 'miter');
237
+ this.pdfDocument.lineCap(vector.lineCap || 'butt'); //TODO: clipping
238
+
239
+ let gradient = null;
240
+
241
+ switch (vector.type) {
242
+ case 'ellipse':
243
+ this.pdfDocument.ellipse(vector.x, vector.y, vector.r1, vector.r2);
244
+
245
+ if (vector.linearGradient) {
246
+ gradient = this.pdfDocument.linearGradient(vector.x - vector.r1, vector.y, vector.x + vector.r1, vector.y);
247
+ }
248
+
249
+ break;
250
+
251
+ case 'rect':
252
+ if (vector.r) {
253
+ this.pdfDocument.roundedRect(vector.x, vector.y, vector.w, vector.h, vector.r);
254
+ } else {
255
+ this.pdfDocument.rect(vector.x, vector.y, vector.w, vector.h);
256
+ }
257
+
258
+ if (vector.linearGradient) {
259
+ gradient = this.pdfDocument.linearGradient(vector.x, vector.y, vector.x + vector.w, vector.y);
260
+ }
261
+
262
+ break;
263
+
264
+ case 'line':
265
+ this.pdfDocument.moveTo(vector.x1, vector.y1);
266
+ this.pdfDocument.lineTo(vector.x2, vector.y2);
267
+ break;
268
+
269
+ case 'polyline':
270
+ if (vector.points.length === 0) {
271
+ break;
272
+ }
273
+
274
+ this.pdfDocument.moveTo(vector.points[0].x, vector.points[0].y);
275
+
276
+ for (let i = 1, l = vector.points.length; i < l; i++) {
277
+ this.pdfDocument.lineTo(vector.points[i].x, vector.points[i].y);
278
+ }
279
+
280
+ if (vector.points.length > 1) {
281
+ let p1 = vector.points[0];
282
+ let pn = vector.points[vector.points.length - 1];
283
+
284
+ if (vector.closePath || p1.x === pn.x && p1.y === pn.y) {
285
+ this.pdfDocument.closePath();
286
+ }
287
+ }
288
+
289
+ break;
290
+
291
+ case 'path':
292
+ this.pdfDocument.path(vector.d);
293
+ break;
294
+ }
295
+
296
+ if (vector.linearGradient && gradient) {
297
+ let step = 1 / (vector.linearGradient.length - 1);
298
+
299
+ for (let i = 0; i < vector.linearGradient.length; i++) {
300
+ gradient.stop(i * step, vector.linearGradient[i]);
301
+ }
302
+
303
+ vector.color = gradient;
304
+ }
305
+
306
+ let patternColor = this.pdfDocument.providePattern(vector.color);
307
+
308
+ if (patternColor !== null) {
309
+ vector.color = patternColor;
310
+ }
311
+
312
+ let fillOpacity = (0, _variableType.isNumber)(vector.fillOpacity) ? vector.fillOpacity : 1;
313
+ let strokeOpacity = (0, _variableType.isNumber)(vector.strokeOpacity) ? vector.strokeOpacity : 1;
314
+
315
+ if (vector.color && vector.lineColor) {
316
+ this.pdfDocument.fillColor(vector.color, fillOpacity);
317
+ this.pdfDocument.strokeColor(vector.lineColor, strokeOpacity);
318
+ this.pdfDocument.fillAndStroke();
319
+ } else if (vector.color) {
320
+ this.pdfDocument.fillColor(vector.color, fillOpacity);
321
+ this.pdfDocument.fill();
322
+ } else {
323
+ this.pdfDocument.strokeColor(vector.lineColor || 'black', strokeOpacity);
324
+ this.pdfDocument.stroke();
325
+ }
326
+ }
327
+
328
+ renderImage(image) {
329
+ let opacity = (0, _variableType.isNumber)(image.opacity) ? image.opacity : 1;
330
+ this.pdfDocument.opacity(opacity);
331
+
332
+ if (image.cover) {
333
+ const align = image.cover.align || 'center';
334
+ const valign = image.cover.valign || 'center';
335
+ const width = image.cover.width ? image.cover.width : image.width;
336
+ const height = image.cover.height ? image.cover.height : image.height;
337
+ this.pdfDocument.save();
338
+ this.pdfDocument.rect(image.x, image.y, width, height).clip();
339
+ this.pdfDocument.image(image.image, image.x, image.y, {
340
+ cover: [width, height],
341
+ align: align,
342
+ valign: valign
343
+ });
344
+ this.pdfDocument.restore();
345
+ } else {
346
+ this.pdfDocument.image(image.image, image.x, image.y, {
347
+ width: image._width,
348
+ height: image._height
349
+ });
350
+ }
351
+
352
+ if (image.link) {
353
+ this.pdfDocument.link(image.x, image.y, image._width, image._height, image.link);
354
+ }
355
+
356
+ if (image.linkToPage) {
357
+ this.pdfDocument.ref({
358
+ Type: 'Action',
359
+ S: 'GoTo',
360
+ D: [image.linkToPage, 0, 0]
361
+ }).end();
362
+ this.pdfDocument.annotate(image.x, image.y, image._width, image._height, {
363
+ Subtype: 'Link',
364
+ Dest: [image.linkToPage - 1, 'XYZ', null, null, null]
365
+ });
366
+ }
367
+
368
+ if (image.linkToDestination) {
369
+ this.pdfDocument.goTo(image.x, image.y, image._width, image._height, image.linkToDestination);
370
+ }
371
+
372
+ if (image.linkToFile) {
373
+ const attachment = this.pdfDocument.provideAttachment(image.linkToFile);
374
+ this.pdfDocument.fileAnnotation(image.x, image.y, image._width, image._height, attachment, // add empty rectangle as file annotation appearance with the same size as the rendered image
375
+ {
376
+ AP: {
377
+ N: {
378
+ Type: 'XObject',
379
+ Subtype: 'Form',
380
+ FormType: 1,
381
+ BBox: [image.x, image.y, image._width, image._height]
382
+ }
383
+ }
384
+ });
385
+ }
386
+ }
387
+
388
+ renderSVG(svg) {
389
+ let options = Object.assign({
390
+ width: svg._width,
391
+ height: svg._height,
392
+ assumePt: true
393
+ }, svg.options);
394
+
395
+ options.fontCallback = (family, bold, italic) => {
396
+ let fontsFamily = family.split(',').map(f => f.trim().replace(/('|")/g, ''));
397
+ let font = findFont(this.pdfDocument.fonts, fontsFamily, svg.font || 'Roboto');
398
+ let fontFile = this.pdfDocument.getFontFile(font, bold, italic);
399
+
400
+ if (fontFile === null) {
401
+ let type = this.pdfDocument.getFontType(bold, italic);
402
+ throw new Error(`Font '${font}' in style '${type}' is not defined in the font section of the document definition.`);
403
+ }
404
+
405
+ return fontFile;
406
+ };
407
+
408
+ (0, _svgToPdfkit.default)(this.pdfDocument, svg.svg, svg.x, svg.y, options);
409
+ }
410
+
411
+ renderAttachment(attachment) {
412
+ const file = this.pdfDocument.provideAttachment(attachment.attachment);
413
+ const options = {};
414
+
415
+ if (attachment.icon) {
416
+ options.Name = attachment.icon;
417
+ }
418
+
419
+ this.pdfDocument.fileAnnotation(attachment.x, attachment.y, attachment._width, attachment._height, file, options);
420
+ }
421
+
422
+ beginClip(rect) {
423
+ this.pdfDocument.save();
424
+ this.pdfDocument.addContent(`${rect.x} ${rect.y} ${rect.width} ${rect.height} re`);
425
+ this.pdfDocument.clip();
426
+ }
427
+
428
+ endClip() {
429
+ this.pdfDocument.restore();
430
+ }
431
+
432
+ renderWatermark(page) {
433
+ let watermark = page.watermark;
434
+ this.pdfDocument.fill(watermark.color);
435
+ this.pdfDocument.opacity(watermark.opacity);
436
+ this.pdfDocument.save();
437
+ this.pdfDocument.rotate(watermark.angle, {
438
+ origin: [this.pdfDocument.page.width / 2, this.pdfDocument.page.height / 2]
439
+ });
440
+ let x = this.pdfDocument.page.width / 2 - watermark._size.size.width / 2;
441
+ let y = this.pdfDocument.page.height / 2 - watermark._size.size.height / 2;
442
+ this.pdfDocument._font = watermark.font;
443
+ this.pdfDocument.fontSize(watermark.fontSize);
444
+ this.pdfDocument.text(watermark.text, x, y, {
445
+ lineBreak: false
446
+ });
447
+ this.pdfDocument.restore();
448
+ }
449
+
450
+ _updatePageOrientationInOptions(currentPage) {
451
+ let previousPageOrientation = this.pdfDocument.options.size[0] > this.pdfDocument.options.size[1] ? 'landscape' : 'portrait';
452
+
453
+ if (currentPage.pageSize.orientation !== previousPageOrientation) {
454
+ let width = this.pdfDocument.options.size[0];
455
+ let height = this.pdfDocument.options.size[1];
456
+ this.pdfDocument.options.size = [height, width];
457
+ }
458
+ }
459
+
460
+ }
461
+
462
+ var _default = Renderer;
463
+ exports.default = _default;
@@ -0,0 +1,89 @@
1
+ "use strict";
2
+
3
+ exports.__esModule = true;
4
+ exports.default = void 0;
5
+
6
+ var _xmldoc = _interopRequireDefault(require("xmldoc"));
7
+
8
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
9
+
10
+ /**
11
+ * Strip unit postfix, parse number, but return undefined instead of NaN for bad input
12
+ *
13
+ * @param {string} textVal
14
+ * @returns {?number}
15
+ */
16
+ const stripUnits = textVal => {
17
+ var n = parseFloat(textVal);
18
+
19
+ if (typeof n !== 'number' || isNaN(n)) {
20
+ return undefined;
21
+ }
22
+
23
+ return n;
24
+ };
25
+ /**
26
+ * Make sure it's valid XML and the root tage is <svg/>, returns xmldoc DOM
27
+ *
28
+ * @param {string} svgString
29
+ * @returns {object}
30
+ */
31
+
32
+
33
+ const parseSVG = svgString => {
34
+ var doc;
35
+
36
+ try {
37
+ doc = new _xmldoc.default.XmlDocument(svgString);
38
+ } catch (err) {
39
+ throw new Error('SVGMeasure: ' + err);
40
+ }
41
+
42
+ if (doc.name !== "svg") {
43
+ throw new Error('SVGMeasure: expected <svg> document');
44
+ }
45
+
46
+ return doc;
47
+ };
48
+
49
+ class SVGMeasure {
50
+ constructor() {}
51
+
52
+ measureSVG(svgString) {
53
+ let doc = parseSVG(svgString);
54
+ let docWidth = stripUnits(doc.attr.width);
55
+ let docHeight = stripUnits(doc.attr.height);
56
+
57
+ if ((docWidth === undefined || docHeight === undefined) && typeof doc.attr.viewBox === 'string') {
58
+ let viewBoxParts = doc.attr.viewBox.split(/[,\s]+/);
59
+
60
+ if (viewBoxParts.length !== 4) {
61
+ throw new Error("Unexpected svg viewbox format, should have 4 entries but found: '" + doc.attr.viewBox + "'");
62
+ }
63
+
64
+ if (docWidth === undefined) {
65
+ docWidth = stripUnits(viewBoxParts[2]);
66
+ }
67
+
68
+ if (docHeight === undefined) {
69
+ docHeight = stripUnits(viewBoxParts[3]);
70
+ }
71
+ }
72
+
73
+ return {
74
+ width: docWidth,
75
+ height: docHeight
76
+ };
77
+ }
78
+
79
+ writeDimensions(svgString, dimensions) {
80
+ let doc = parseSVG(svgString);
81
+ doc.attr.width = "" + dimensions.width;
82
+ doc.attr.height = "" + dimensions.height;
83
+ return doc.toString();
84
+ }
85
+
86
+ }
87
+
88
+ var _default = SVGMeasure;
89
+ exports.default = _default;