pdfmake 0.1.65 → 0.1.69
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.
- package/build/pdfmake.js +12257 -5176
- package/build/pdfmake.js.map +1 -1
- package/build/pdfmake.min.js +2 -37
- package/build/pdfmake.min.js.map +1 -1
- package/package.json +74 -69
- package/src/browser-extensions/URLBrowserResolver.js +88 -0
- package/src/browser-extensions/pdfMake.js +65 -12
- package/src/browser-extensions/virtual-fs.js +6 -0
- package/src/imageMeasure.js +6 -0
- package/src/printer.js +39 -5
- package/src/styleContextStack.js +3 -1
- package/src/svgMeasure.js +45 -81
- package/src/textTools.js +9 -0
- package/webpack.config.js +134 -114
package/package.json
CHANGED
|
@@ -1,69 +1,74 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "pdfmake",
|
|
3
|
-
"version": "0.1.
|
|
4
|
-
"description": "Client/server side PDF printing in pure JavaScript",
|
|
5
|
-
"main": "src/printer.js",
|
|
6
|
-
"browser": "build/pdfmake.js",
|
|
7
|
-
"directories": {
|
|
8
|
-
"test": "tests"
|
|
9
|
-
},
|
|
10
|
-
"dependencies": {
|
|
11
|
-
"iconv-lite": "^0.
|
|
12
|
-
"linebreak": "^1.0.2",
|
|
13
|
-
"pdfkit": "^0.11.0",
|
|
14
|
-
"svg-to-pdfkit": "^0.1.8"
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
"@babel/
|
|
19
|
-
"@babel/
|
|
20
|
-
"babel-
|
|
21
|
-
"
|
|
22
|
-
"
|
|
23
|
-
"
|
|
24
|
-
"
|
|
25
|
-
"
|
|
26
|
-
"
|
|
27
|
-
"
|
|
28
|
-
"gulp
|
|
29
|
-
"gulp-
|
|
30
|
-
"gulp-
|
|
31
|
-
"
|
|
32
|
-
"
|
|
33
|
-
"
|
|
34
|
-
"
|
|
35
|
-
"
|
|
36
|
-
"
|
|
37
|
-
"webpack": "
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
"
|
|
43
|
-
},
|
|
44
|
-
"
|
|
45
|
-
"
|
|
46
|
-
"
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
"
|
|
51
|
-
"
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
"
|
|
58
|
-
|
|
59
|
-
"
|
|
60
|
-
"
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
1
|
+
{
|
|
2
|
+
"name": "pdfmake",
|
|
3
|
+
"version": "0.1.69",
|
|
4
|
+
"description": "Client/server side PDF printing in pure JavaScript",
|
|
5
|
+
"main": "src/printer.js",
|
|
6
|
+
"browser": "build/pdfmake.js",
|
|
7
|
+
"directories": {
|
|
8
|
+
"test": "tests"
|
|
9
|
+
},
|
|
10
|
+
"dependencies": {
|
|
11
|
+
"iconv-lite": "^0.6.2",
|
|
12
|
+
"linebreak": "^1.0.2",
|
|
13
|
+
"pdfkit": "^0.11.0",
|
|
14
|
+
"svg-to-pdfkit": "^0.1.8",
|
|
15
|
+
"xmldoc": "^1.1.2"
|
|
16
|
+
},
|
|
17
|
+
"devDependencies": {
|
|
18
|
+
"@babel/core": "^7.12.10",
|
|
19
|
+
"@babel/plugin-transform-modules-commonjs": "^7.12.1",
|
|
20
|
+
"@babel/preset-env": "^7.12.11",
|
|
21
|
+
"babel-loader": "^8.2.2",
|
|
22
|
+
"brfs": "^2.0.2",
|
|
23
|
+
"core-js": "^3.8.1",
|
|
24
|
+
"eslint-plugin-jsdoc": "^30.7.9",
|
|
25
|
+
"expose-loader": "^1.0.3",
|
|
26
|
+
"fancy-log": "^1.3.3",
|
|
27
|
+
"file-saver": "^2.0.5",
|
|
28
|
+
"gulp": "^4.0.2",
|
|
29
|
+
"gulp-each": "^0.5.0",
|
|
30
|
+
"gulp-eslint": "^6.0.0",
|
|
31
|
+
"gulp-file-contents-to-json": "^0.2.2",
|
|
32
|
+
"gulp-spawn-mocha": "^6.0.0",
|
|
33
|
+
"mocha": "7.2.0",
|
|
34
|
+
"rewire": "^5.0.0",
|
|
35
|
+
"sinon": "^9.2.2",
|
|
36
|
+
"string-replace-webpack-plugin": "^0.1.3",
|
|
37
|
+
"terser-webpack-plugin": "4.2.3",
|
|
38
|
+
"transform-loader": "^0.2.4",
|
|
39
|
+
"webpack": "^4.44.2"
|
|
40
|
+
},
|
|
41
|
+
"engines": {
|
|
42
|
+
"node": ">=8"
|
|
43
|
+
},
|
|
44
|
+
"scripts": {
|
|
45
|
+
"build": "gulp build",
|
|
46
|
+
"test": "gulp",
|
|
47
|
+
"playground": "node dev-playground/server.js"
|
|
48
|
+
},
|
|
49
|
+
"repository": {
|
|
50
|
+
"type": "git",
|
|
51
|
+
"url": "git://github.com/bpampuch/pdfmake.git"
|
|
52
|
+
},
|
|
53
|
+
"keywords": [
|
|
54
|
+
"pdf",
|
|
55
|
+
"javascript",
|
|
56
|
+
"printing",
|
|
57
|
+
"layout"
|
|
58
|
+
],
|
|
59
|
+
"author": "Bartek Pampuch <bartosz.pampuch@gmail.com>",
|
|
60
|
+
"license": "MIT",
|
|
61
|
+
"bugs": {
|
|
62
|
+
"url": "https://github.com/bpampuch/pdfmake/issues"
|
|
63
|
+
},
|
|
64
|
+
"homepage": "http://pdfmake.org",
|
|
65
|
+
"config": {
|
|
66
|
+
"blanket": {
|
|
67
|
+
"pattern": "src",
|
|
68
|
+
"data-cover-never": [
|
|
69
|
+
"node_modules",
|
|
70
|
+
"tests"
|
|
71
|
+
]
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
// Internet Explorer polyfills
|
|
4
|
+
if (typeof window !== 'undefined' && !window.Promise) {
|
|
5
|
+
require('core-js/features/promise');
|
|
6
|
+
}
|
|
7
|
+
require('core-js/es/object/values');
|
|
8
|
+
|
|
9
|
+
var fetchUrl = function (url) {
|
|
10
|
+
return new Promise(function (resolve, reject) {
|
|
11
|
+
var xhr = new XMLHttpRequest();
|
|
12
|
+
xhr.open('GET', url, true);
|
|
13
|
+
xhr.responseType = 'arraybuffer';
|
|
14
|
+
|
|
15
|
+
xhr.onreadystatechange = function () {
|
|
16
|
+
if (xhr.readyState !== 4) {
|
|
17
|
+
return;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
var ok = xhr.status >= 200 && xhr.status < 300;
|
|
21
|
+
if (!ok) {
|
|
22
|
+
setTimeout(function () {
|
|
23
|
+
reject(new TypeError('Failed to fetch (url: "' + url + '")'));
|
|
24
|
+
}, 0);
|
|
25
|
+
}
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
xhr.onload = function () {
|
|
29
|
+
var ok = xhr.status >= 200 && xhr.status < 300;
|
|
30
|
+
if (ok) {
|
|
31
|
+
resolve(xhr.response);
|
|
32
|
+
}
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
xhr.onerror = function () {
|
|
36
|
+
setTimeout(function () {
|
|
37
|
+
reject(new TypeError('Network request failed (url: "' + url + '")'));
|
|
38
|
+
}, 0);
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
xhr.ontimeout = function () {
|
|
42
|
+
setTimeout(function () {
|
|
43
|
+
reject(new TypeError('Network request failed (url: "' + url + '")'));
|
|
44
|
+
}, 0);
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
xhr.send();
|
|
48
|
+
});
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
function URLBrowserResolver(fs) {
|
|
52
|
+
this.fs = fs;
|
|
53
|
+
this.resolving = {};
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
URLBrowserResolver.prototype.resolve = function (url) {
|
|
57
|
+
if (!this.resolving[url]) {
|
|
58
|
+
var _this = this;
|
|
59
|
+
this.resolving[url] = new Promise(function (resolve, reject) {
|
|
60
|
+
if (url.toLowerCase().indexOf('https://') === 0 || url.toLowerCase().indexOf('http://') === 0) {
|
|
61
|
+
fetchUrl(url).then(function (buffer) {
|
|
62
|
+
_this.fs.writeFileSync(url, buffer);
|
|
63
|
+
resolve();
|
|
64
|
+
}, function (result) {
|
|
65
|
+
reject(result);
|
|
66
|
+
});
|
|
67
|
+
} else {
|
|
68
|
+
// cannot be resolved
|
|
69
|
+
resolve();
|
|
70
|
+
}
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
return this.resolving[url];
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
URLBrowserResolver.prototype.resolved = function () {
|
|
78
|
+
var _this = this;
|
|
79
|
+
return new Promise(function (resolve, reject) {
|
|
80
|
+
Promise.all(Object.values(_this.resolving)).then(function () {
|
|
81
|
+
resolve();
|
|
82
|
+
}, function (result) {
|
|
83
|
+
reject(result);
|
|
84
|
+
});
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
module.exports = URLBrowserResolver;
|
|
@@ -30,7 +30,7 @@ function canCreatePdf() {
|
|
|
30
30
|
return true;
|
|
31
31
|
}
|
|
32
32
|
|
|
33
|
-
Document.prototype._createDoc = function (options) {
|
|
33
|
+
Document.prototype._createDoc = function (options, cb) {
|
|
34
34
|
options = options || {};
|
|
35
35
|
if (this.tableLayouts) {
|
|
36
36
|
options.tableLayouts = this.tableLayouts;
|
|
@@ -41,9 +41,49 @@ Document.prototype._createDoc = function (options) {
|
|
|
41
41
|
var printer = new PdfPrinter(this.fonts);
|
|
42
42
|
require('fs').bindFS(this.vfs); // bind virtual file system to file system
|
|
43
43
|
|
|
44
|
-
|
|
44
|
+
if (!isFunction(cb)) {
|
|
45
|
+
var doc = printer.createPdfKitDocument(this.docDefinition, options);
|
|
45
46
|
|
|
46
|
-
|
|
47
|
+
return doc;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
var URLBrowserResolver = require('./URLBrowserResolver');
|
|
51
|
+
var urlResolver = new URLBrowserResolver(require('fs'));
|
|
52
|
+
|
|
53
|
+
for (var font in this.fonts) {
|
|
54
|
+
if (this.fonts.hasOwnProperty(font)) {
|
|
55
|
+
if (this.fonts[font].normal) {
|
|
56
|
+
urlResolver.resolve(this.fonts[font].normal);
|
|
57
|
+
}
|
|
58
|
+
if (this.fonts[font].bold) {
|
|
59
|
+
urlResolver.resolve(this.fonts[font].bold);
|
|
60
|
+
}
|
|
61
|
+
if (this.fonts[font].italics) {
|
|
62
|
+
urlResolver.resolve(this.fonts[font].italics);
|
|
63
|
+
}
|
|
64
|
+
if (this.fonts[font].bolditalics) {
|
|
65
|
+
urlResolver.resolve(this.fonts[font].bolditalics);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
if (this.docDefinition.images) {
|
|
71
|
+
for (var image in this.docDefinition.images) {
|
|
72
|
+
if (this.docDefinition.images.hasOwnProperty(image)) {
|
|
73
|
+
urlResolver.resolve(this.docDefinition.images[image]);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
var _this = this;
|
|
79
|
+
|
|
80
|
+
urlResolver.resolved().then(function () {
|
|
81
|
+
var doc = printer.createPdfKitDocument(_this.docDefinition, options);
|
|
82
|
+
|
|
83
|
+
cb(doc);
|
|
84
|
+
}, function (result) {
|
|
85
|
+
throw result;
|
|
86
|
+
});
|
|
47
87
|
};
|
|
48
88
|
|
|
49
89
|
Document.prototype._flushDoc = function (doc, callback) {
|
|
@@ -67,9 +107,12 @@ Document.prototype._getPages = function (options, cb) {
|
|
|
67
107
|
if (!cb) {
|
|
68
108
|
throw '_getPages is an async method and needs a callback argument';
|
|
69
109
|
}
|
|
70
|
-
var
|
|
71
|
-
|
|
72
|
-
|
|
110
|
+
var _this = this;
|
|
111
|
+
|
|
112
|
+
this._createDoc(options, function (doc) {
|
|
113
|
+
_this._flushDoc(doc, function (ignoreBuffer, pages) {
|
|
114
|
+
cb(pages);
|
|
115
|
+
});
|
|
73
116
|
});
|
|
74
117
|
};
|
|
75
118
|
|
|
@@ -203,15 +246,25 @@ Document.prototype.getBuffer = function (cb, options) {
|
|
|
203
246
|
if (!cb) {
|
|
204
247
|
throw 'getBuffer is an async method and needs a callback argument';
|
|
205
248
|
}
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
249
|
+
|
|
250
|
+
var _this = this;
|
|
251
|
+
|
|
252
|
+
this._createDoc(options, function (doc) {
|
|
253
|
+
_this._flushDoc(doc, function (buffer) {
|
|
254
|
+
cb(buffer);
|
|
255
|
+
});
|
|
209
256
|
});
|
|
210
257
|
};
|
|
211
258
|
|
|
212
|
-
Document.prototype.getStream = function (options) {
|
|
213
|
-
|
|
214
|
-
|
|
259
|
+
Document.prototype.getStream = function (options, cb) {
|
|
260
|
+
if (!isFunction(cb)) {
|
|
261
|
+
var doc = this._createDoc(options);
|
|
262
|
+
return doc;
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
this._createDoc(options, function (doc) {
|
|
266
|
+
cb(doc);
|
|
267
|
+
});
|
|
215
268
|
};
|
|
216
269
|
|
|
217
270
|
module.exports = {
|
|
@@ -5,6 +5,12 @@ function VirtualFileSystem() {
|
|
|
5
5
|
this.dataSystem = {};
|
|
6
6
|
}
|
|
7
7
|
|
|
8
|
+
VirtualFileSystem.prototype.existsSync = function (filename) {
|
|
9
|
+
filename = fixFilename(filename);
|
|
10
|
+
return typeof this.fileSystem[filename] !== 'undefined'
|
|
11
|
+
|| typeof this.dataSystem[filename] !== 'undefined';
|
|
12
|
+
}
|
|
13
|
+
|
|
8
14
|
VirtualFileSystem.prototype.readFileSync = function (filename, options) {
|
|
9
15
|
filename = fixFilename(filename);
|
|
10
16
|
|
package/src/imageMeasure.js
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
+
var fs = require('fs');
|
|
4
|
+
|
|
3
5
|
function ImageMeasure(pdfKitDoc, imageDictionary) {
|
|
4
6
|
this.pdfKitDoc = pdfKitDoc;
|
|
5
7
|
this.imageDictionary = imageDictionary || {};
|
|
@@ -33,6 +35,10 @@ ImageMeasure.prototype.measureImage = function (src) {
|
|
|
33
35
|
return src;
|
|
34
36
|
}
|
|
35
37
|
|
|
38
|
+
if (fs.existsSync(img)) {
|
|
39
|
+
return fs.readFileSync(img);
|
|
40
|
+
}
|
|
41
|
+
|
|
36
42
|
var index = img.indexOf('base64,');
|
|
37
43
|
if (index < 0) {
|
|
38
44
|
return that.imageDictionary[src];
|
package/src/printer.js
CHANGED
|
@@ -207,6 +207,8 @@ function calculatePageHeight(pages, margins) {
|
|
|
207
207
|
return item.item.getHeight();
|
|
208
208
|
} else if (item.item._height) {
|
|
209
209
|
return item.item._height;
|
|
210
|
+
} else if (item.type === 'vector') {
|
|
211
|
+
return item.item.y1 > item.item.y2 ? item.item.y1 : item.item.y2;
|
|
210
212
|
} else {
|
|
211
213
|
// TODO: add support for next item types
|
|
212
214
|
return 0;
|
|
@@ -214,7 +216,7 @@ function calculatePageHeight(pages, margins) {
|
|
|
214
216
|
}
|
|
215
217
|
|
|
216
218
|
function getBottomPosition(item) {
|
|
217
|
-
var top = item.item.y;
|
|
219
|
+
var top = item.item.y || 0;
|
|
218
220
|
var height = getItemHeight(item);
|
|
219
221
|
return top + height;
|
|
220
222
|
}
|
|
@@ -406,6 +408,25 @@ function renderPages(pages, fontProvider, pdfKitDoc, progressCallback) {
|
|
|
406
408
|
}
|
|
407
409
|
}
|
|
408
410
|
|
|
411
|
+
/**
|
|
412
|
+
* Shift the "y" height of the text baseline up or down (superscript or subscript,
|
|
413
|
+
* respectively). The exact shift can / should be changed according to standard
|
|
414
|
+
* conventions.
|
|
415
|
+
*
|
|
416
|
+
* @param {number} y
|
|
417
|
+
* @param {any} inline
|
|
418
|
+
*/
|
|
419
|
+
function offsetText(y, inline) {
|
|
420
|
+
var newY = y;
|
|
421
|
+
if (inline.sup) {
|
|
422
|
+
newY -= inline.fontSize * 0.75;
|
|
423
|
+
}
|
|
424
|
+
if (inline.sub) {
|
|
425
|
+
newY += inline.fontSize * 0.35;
|
|
426
|
+
}
|
|
427
|
+
return newY;
|
|
428
|
+
}
|
|
429
|
+
|
|
409
430
|
function renderLine(line, x, y, pdfKitDoc) {
|
|
410
431
|
function preparePageNodeRefLine(_pageNodeRef, inline) {
|
|
411
432
|
var newWidth;
|
|
@@ -481,18 +502,20 @@ function renderLine(line, x, y, pdfKitDoc) {
|
|
|
481
502
|
|
|
482
503
|
pdfKitDoc._font = inline.font;
|
|
483
504
|
pdfKitDoc.fontSize(inline.fontSize);
|
|
484
|
-
|
|
505
|
+
|
|
506
|
+
var shiftedY = offsetText(y + shiftToBaseline, inline);
|
|
507
|
+
pdfKitDoc.text(inline.text, x + inline.x, shiftedY, options);
|
|
485
508
|
|
|
486
509
|
if (inline.linkToPage) {
|
|
487
510
|
var _ref = pdfKitDoc.ref({ Type: 'Action', S: 'GoTo', D: [inline.linkToPage, 0, 0] }).end();
|
|
488
|
-
pdfKitDoc.annotate(x + inline.x,
|
|
511
|
+
pdfKitDoc.annotate(x + inline.x, shiftedY, inline.width, inline.height, {
|
|
489
512
|
Subtype: 'Link',
|
|
490
513
|
Dest: [inline.linkToPage - 1, 'XYZ', null, null, null]
|
|
491
514
|
});
|
|
492
515
|
}
|
|
493
516
|
|
|
494
517
|
}
|
|
495
|
-
|
|
518
|
+
// Decorations won't draw correctly for superscript
|
|
496
519
|
textDecorator.drawDecorations(line, x, y, pdfKitDoc);
|
|
497
520
|
}
|
|
498
521
|
|
|
@@ -607,7 +630,18 @@ function renderVector(vector, pdfKitDoc) {
|
|
|
607
630
|
function renderImage(image, x, y, pdfKitDoc) {
|
|
608
631
|
var opacity = isNumber(image.opacity) ? image.opacity : 1;
|
|
609
632
|
pdfKitDoc.opacity(opacity);
|
|
610
|
-
|
|
633
|
+
if (image.cover) {
|
|
634
|
+
var align = image.cover.align || 'center';
|
|
635
|
+
var valign = image.cover.valign || 'center';
|
|
636
|
+
var width = image.cover.width ? image.cover.width : image.width;
|
|
637
|
+
var height = image.cover.height ? image.cover.height : image.height;
|
|
638
|
+
pdfKitDoc.save();
|
|
639
|
+
pdfKitDoc.rect(image.x, image.y, width, height).clip();
|
|
640
|
+
pdfKitDoc.image(image.image, image.x, image.y, { cover: [width, height], align, valign });
|
|
641
|
+
pdfKitDoc.restore();
|
|
642
|
+
} else {
|
|
643
|
+
pdfKitDoc.image(image.image, image.x, image.y, { width: image._width, height: image._height });
|
|
644
|
+
}
|
|
611
645
|
if (image.link) {
|
|
612
646
|
pdfKitDoc.link(image.x, image.y, image._width, image._height, image.link);
|
|
613
647
|
}
|
package/src/styleContextStack.js
CHANGED
|
@@ -103,7 +103,9 @@ StyleContextStack.prototype.autopush = function (item) {
|
|
|
103
103
|
'characterSpacing',
|
|
104
104
|
'noWrap',
|
|
105
105
|
'markerColor',
|
|
106
|
-
'leadingIndent'
|
|
106
|
+
'leadingIndent',
|
|
107
|
+
'sup',
|
|
108
|
+
'sub'
|
|
107
109
|
//'tableCellPadding'
|
|
108
110
|
// 'cellBorder',
|
|
109
111
|
// 'headerCellBorder',
|
package/src/svgMeasure.js
CHANGED
|
@@ -1,106 +1,70 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
}
|
|
3
|
+
var xmldoc = require('xmldoc');
|
|
5
4
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
5
|
+
/** Strip unit postfix, parse number, but return undefined instead of NaN for bad input */
|
|
6
|
+
function stripUnits(textVal) {
|
|
7
|
+
var n = parseFloat(textVal);
|
|
8
|
+
if (typeof n !== 'number' || isNaN(n)) {
|
|
9
|
+
return undefined;
|
|
10
|
+
}
|
|
11
|
+
return n;
|
|
12
|
+
}
|
|
11
13
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
14
|
+
/** Make sure it's valid XML and the root tage is <svg/>, returns xmldoc DOM */
|
|
15
|
+
function parseSVG(svgString) {
|
|
16
|
+
var doc;
|
|
17
|
+
|
|
18
|
+
try {
|
|
19
|
+
doc = new xmldoc.XmlDocument(svgString);
|
|
20
|
+
} catch (err) {
|
|
21
|
+
throw new Error('SVGMeasure: ' + err);
|
|
15
22
|
}
|
|
16
23
|
|
|
17
|
-
|
|
18
|
-
|
|
24
|
+
if (doc.name !== "svg") {
|
|
25
|
+
throw new Error('SVGMeasure: expected <svg> document');
|
|
26
|
+
}
|
|
19
27
|
|
|
20
|
-
|
|
21
|
-
|
|
28
|
+
return doc;
|
|
29
|
+
}
|
|
22
30
|
|
|
23
|
-
|
|
24
|
-
|
|
31
|
+
function SVGMeasure() {
|
|
32
|
+
}
|
|
25
33
|
|
|
26
|
-
|
|
27
|
-
return {
|
|
28
|
-
width: widthMatches ? +widthMatches[1] : undefined,
|
|
29
|
-
height: heightMatches ? +heightMatches[1] : undefined
|
|
30
|
-
};
|
|
31
|
-
}
|
|
32
|
-
};
|
|
34
|
+
SVGMeasure.prototype.measureSVG = function (svgString) {
|
|
33
35
|
|
|
34
|
-
|
|
35
|
-
var svgNode = this.getSVGNode(svgString);
|
|
36
|
+
var doc = parseSVG(svgString);
|
|
36
37
|
|
|
37
|
-
var
|
|
38
|
-
|
|
39
|
-
var viewboxStr = viewboxMatches[1];
|
|
40
|
-
var allVieboxEntries = viewboxStr.split(" ");
|
|
38
|
+
var docWidth = stripUnits(doc.attr.width);
|
|
39
|
+
var docHeight = stripUnits(doc.attr.height);
|
|
41
40
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
}
|
|
41
|
+
if ((docWidth == undefined || docHeight == undefined) && typeof doc.attr.viewBox == 'string') {
|
|
42
|
+
var viewBoxParts = doc.attr.viewBox.split(/[,\s]+/);
|
|
43
|
+
if (viewBoxParts.length !== 4) {
|
|
44
|
+
throw new Error("Unexpected svg viewbox format, should have 4 entries but found: '" + doc.attr.viewBox + "'");
|
|
47
45
|
}
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
46
|
+
if (docWidth == undefined) {
|
|
47
|
+
docWidth = stripUnits(viewBoxParts[2]);
|
|
48
|
+
}
|
|
49
|
+
if (docHeight == undefined) {
|
|
50
|
+
docHeight = stripUnits(viewBoxParts[3]);
|
|
51
51
|
}
|
|
52
|
-
|
|
53
|
-
throw new Error("Unexpected svg viewbox format, should have 4 entries but found: '" + viewboxStr + "'");
|
|
54
52
|
}
|
|
55
|
-
};
|
|
56
|
-
|
|
57
|
-
SVGMeasure.prototype.measureSVG = function (svgString) {
|
|
58
|
-
|
|
59
|
-
var heightAndWidth = this.getHeightAndWidth(svgString);
|
|
60
|
-
var viewboxHeightAndWidth = this.getViewboxHeightAndWidth(svgString);
|
|
61
53
|
|
|
62
|
-
return
|
|
54
|
+
return {
|
|
55
|
+
width: docWidth,
|
|
56
|
+
height: docHeight
|
|
57
|
+
};
|
|
63
58
|
};
|
|
64
59
|
|
|
65
60
|
SVGMeasure.prototype.writeDimensions = function (svgString, dimensions) {
|
|
66
61
|
|
|
67
|
-
var
|
|
68
|
-
|
|
69
|
-
if (svgNode) {
|
|
70
|
-
|
|
71
|
-
var nodeDimensions = this.getHeightAndWidth(svgString);
|
|
72
|
-
|
|
73
|
-
if (dimensions.width) {
|
|
74
|
-
|
|
75
|
-
var newWidth = 'width="' + dimensions.width + '"';
|
|
62
|
+
var doc = parseSVG(svgString);
|
|
76
63
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
svgNode = svgNode.replace(/width="[0-9]+(\.[0-9]+)?(em|ex|px|in|cm|mm|pt|pc|%)?"/, newWidth);
|
|
80
|
-
} else {
|
|
81
|
-
// insert new width
|
|
82
|
-
svgNode = svgNode.replace(">", " " + newWidth + ">");
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
if (dimensions.height) {
|
|
87
|
-
|
|
88
|
-
var newHeight = 'height="' + dimensions.height + '"';
|
|
89
|
-
|
|
90
|
-
if (nodeDimensions && nodeDimensions.height) {
|
|
91
|
-
// replace existing height
|
|
92
|
-
svgNode = svgNode.replace(/height="[0-9]+(\.[0-9]+)?(em|ex|px|in|cm|mm|pt|pc|%)?"/, newHeight);
|
|
93
|
-
} else {
|
|
94
|
-
// insert new height
|
|
95
|
-
svgNode = svgNode.replace(">", " " + newHeight + ">");
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
// insert updated svg node
|
|
100
|
-
return svgString.replace(/<svg(.*?)>/, svgNode);
|
|
101
|
-
}
|
|
64
|
+
doc.attr.width = "" + dimensions.width;
|
|
65
|
+
doc.attr.height = "" + dimensions.height;
|
|
102
66
|
|
|
103
|
-
return
|
|
67
|
+
return doc.toString();
|
|
104
68
|
};
|
|
105
69
|
|
|
106
70
|
module.exports = SVGMeasure;
|
package/src/textTools.js
CHANGED
|
@@ -315,6 +315,13 @@ function measure(fontProvider, textArray, styleContextStack) {
|
|
|
315
315
|
var preserveLeadingSpaces = getStyleProperty(item, styleContextStack, 'preserveLeadingSpaces', false);
|
|
316
316
|
var preserveTrailingSpaces = getStyleProperty(item, styleContextStack, 'preserveTrailingSpaces', false);
|
|
317
317
|
var opacity = getStyleProperty(item, styleContextStack, 'opacity', 1);
|
|
318
|
+
var sup = getStyleProperty(item, styleContextStack, 'sup', false);
|
|
319
|
+
var sub = getStyleProperty(item, styleContextStack, 'sub', false);
|
|
320
|
+
|
|
321
|
+
if ((sup || sub) && item.fontSize === undefined) {
|
|
322
|
+
// font size reduction taken from here: https://en.wikipedia.org/wiki/Subscript_and_superscript#Desktop_publishing
|
|
323
|
+
fontSize *= 0.58
|
|
324
|
+
}
|
|
318
325
|
|
|
319
326
|
var font = fontProvider.provideFont(fontName, bold, italics);
|
|
320
327
|
|
|
@@ -352,6 +359,8 @@ function measure(fontProvider, textArray, styleContextStack) {
|
|
|
352
359
|
item.linkToDestination = linkToDestination;
|
|
353
360
|
item.noWrap = noWrap;
|
|
354
361
|
item.opacity = opacity;
|
|
362
|
+
item.sup = sup;
|
|
363
|
+
item.sub = sub;
|
|
355
364
|
});
|
|
356
365
|
|
|
357
366
|
return normalized;
|