@ohos-ports/oslllo-svg2 5.0.0-beta.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +62 -0
- package/package.json +68 -0
- package/src/color.js +37 -0
- package/src/constants.js +13 -0
- package/src/constructor.js +70 -0
- package/src/error.js +20 -0
- package/src/index.js +8 -0
- package/src/option.js +51 -0
- package/src/output.js +135 -0
- package/src/processor.js +106 -0
- package/src/resize.js +27 -0
- package/src/svg.js +204 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2020 oslllo
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+

|
|
2
|
+
|
|
3
|
+
[](https://github.com/oslllo/svg2/actions/workflows/ci.test.yml)
|
|
4
|
+
[](https://www.npmjs.com/package/oslllo-svg2)
|
|
5
|
+
[](https://coveralls.io/github/oslllo/svg2?branch=master)
|
|
6
|
+
|
|
7
|
+
## 🎉 v1.0.0 Removed `Canvas & JSDOM` no more slow `npm install` cycles.
|
|
8
|
+
|
|
9
|
+
## Documentation, Installation, and Usage Instructions
|
|
10
|
+
|
|
11
|
+
See the full installation and usage documentation [HERE](https://docs.oslllo.com/svg2/master/).
|
|
12
|
+
|
|
13
|
+
## The Objective
|
|
14
|
+
|
|
15
|
+
I wanted to convert `SVGs` into diffrent image formats.
|
|
16
|
+
|
|
17
|
+
## The Problem / Why
|
|
18
|
+
|
|
19
|
+
Converting a `SVG` into an image turns out to not be a simple and straight forward as it may seem. Multiple packages already exist on `NPM` but they all come with a few caveats (that i don't like).
|
|
20
|
+
|
|
21
|
+
- Some use `puppeteer` which requires you to download a browser like chromium **(130mb download)**
|
|
22
|
+
- Some do not support `Node` **(work in browsers only)**
|
|
23
|
+
- Some support `CLI` only.
|
|
24
|
+
- Some only convert to `png`
|
|
25
|
+
|
|
26
|
+
---
|
|
27
|
+
|
|
28
|
+
### Usage Examples
|
|
29
|
+
|
|
30
|
+
#### Convert a SVG2 `png` and save to path (promise)
|
|
31
|
+
|
|
32
|
+
```js
|
|
33
|
+
const Svg2 = require("oslllo-svg2");
|
|
34
|
+
|
|
35
|
+
Svg2("path/to/svg/example.svg")
|
|
36
|
+
.png()
|
|
37
|
+
.toFile("path/to/save/example.png")
|
|
38
|
+
.then(() => {
|
|
39
|
+
console.log("done");
|
|
40
|
+
})
|
|
41
|
+
.catch((error) => {
|
|
42
|
+
throw error;
|
|
43
|
+
});
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
#### Convert a SVG2 `png` and save to path (callback)
|
|
47
|
+
|
|
48
|
+
```js
|
|
49
|
+
const Svg2 = require("oslllo-svg2");
|
|
50
|
+
|
|
51
|
+
Svg2("path/to/svg/example.svg")
|
|
52
|
+
.png()
|
|
53
|
+
.toFile("path/to/save/example.png", (err) => {
|
|
54
|
+
if (err) {
|
|
55
|
+
throw err;
|
|
56
|
+
} else {
|
|
57
|
+
console.log("done");
|
|
58
|
+
}
|
|
59
|
+
});
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
---
|
package/package.json
ADDED
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@ohos-ports/oslllo-svg2",
|
|
3
|
+
"version": "5.0.0-beta.0",
|
|
4
|
+
"description": "Convert a SVG to multiple image formats (without puppeteer or a headless browser)",
|
|
5
|
+
"main": "src/index.js",
|
|
6
|
+
"repository": {
|
|
7
|
+
"type": "git",
|
|
8
|
+
"url": "https://github.com/ohos-ports/ohos-ports.git",
|
|
9
|
+
"directory": "ports/oslllo-svg2/5.0.0"
|
|
10
|
+
},
|
|
11
|
+
"keywords": [
|
|
12
|
+
"svg2",
|
|
13
|
+
"oslllo",
|
|
14
|
+
"convert",
|
|
15
|
+
"svg-png",
|
|
16
|
+
"svg-bmp",
|
|
17
|
+
"svg-jpeg",
|
|
18
|
+
"svg-tiff",
|
|
19
|
+
"svg-image",
|
|
20
|
+
"svg-image",
|
|
21
|
+
"svg-to-png",
|
|
22
|
+
"svg-to-bmp",
|
|
23
|
+
"svg-to-jpeg",
|
|
24
|
+
"svg-to-tiff",
|
|
25
|
+
"svg-to-image",
|
|
26
|
+
"svg-to-element"
|
|
27
|
+
],
|
|
28
|
+
"author": "Ghustavh Ehm <https://github.com/Ghustavh97>",
|
|
29
|
+
"contributors": [
|
|
30
|
+
{
|
|
31
|
+
"name": "Ghustavh Ehm",
|
|
32
|
+
"email": "Ghustavh97@gmail.com",
|
|
33
|
+
"url": "https://github.com/Ghustavh97"
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
"name": "oslllo",
|
|
37
|
+
"email": "oslllo.com@gmail.com",
|
|
38
|
+
"url": "https://github.com/oslllo"
|
|
39
|
+
}
|
|
40
|
+
],
|
|
41
|
+
"license": "MIT",
|
|
42
|
+
"bugs": {
|
|
43
|
+
"url": "https://github.com/ohos-ports/ohos-ports/issues"
|
|
44
|
+
},
|
|
45
|
+
"homepage": "https://docs.oslllo.com/svg2/master",
|
|
46
|
+
"dependencies": {
|
|
47
|
+
"@ohos-ports/resvg-resvg-js": "2.6.2-beta.1",
|
|
48
|
+
"domino": "^2.1.6",
|
|
49
|
+
"jimp": "^0.22.12",
|
|
50
|
+
"oslllo-validator": "^4.0.0"
|
|
51
|
+
},
|
|
52
|
+
"devDependencies": {
|
|
53
|
+
"chai": "^4.3.6",
|
|
54
|
+
"chai-as-promised": "^7.1.1",
|
|
55
|
+
"coveralls": "^3.1.1",
|
|
56
|
+
"fs-extra": "^10.1.0",
|
|
57
|
+
"looks-same": "^7.3.0",
|
|
58
|
+
"mocha": "^11.7.5",
|
|
59
|
+
"mocha-lcov-reporter": "^1.3.0",
|
|
60
|
+
"nyc": "^15.1.0"
|
|
61
|
+
},
|
|
62
|
+
"files": [
|
|
63
|
+
"src/",
|
|
64
|
+
"LICENSE",
|
|
65
|
+
"README.md",
|
|
66
|
+
"package.json"
|
|
67
|
+
]
|
|
68
|
+
}
|
package/src/color.js
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
const error = require("./error");
|
|
4
|
+
const is = require("oslllo-validator");
|
|
5
|
+
|
|
6
|
+
function background(options) {
|
|
7
|
+
if (is.object(options)) {
|
|
8
|
+
this.options.update("background", options);
|
|
9
|
+
} else if (is.hexColor(options)) {
|
|
10
|
+
this.options.update("background", { color: options });
|
|
11
|
+
} else {
|
|
12
|
+
throw error.invalidParameterError(
|
|
13
|
+
"options",
|
|
14
|
+
"object or hex color string",
|
|
15
|
+
options
|
|
16
|
+
);
|
|
17
|
+
}
|
|
18
|
+
options = this.options.get("background");
|
|
19
|
+
if (
|
|
20
|
+
!is.hexColor(options.color) ||
|
|
21
|
+
(is.number(Number(options.color)) && !is.actualNaN(Number(options.color)))
|
|
22
|
+
) {
|
|
23
|
+
throw error.invalidParameterError(
|
|
24
|
+
"background.color",
|
|
25
|
+
"hex color string",
|
|
26
|
+
options
|
|
27
|
+
);
|
|
28
|
+
}
|
|
29
|
+
this.output.background = options;
|
|
30
|
+
return this;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
module.exports = function (Svg2) {
|
|
34
|
+
Object.assign(Svg2.prototype, {
|
|
35
|
+
background: background,
|
|
36
|
+
});
|
|
37
|
+
};
|
package/src/constants.js
ADDED
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
const fs = require("fs");
|
|
4
|
+
const jimp = require("jimp");
|
|
5
|
+
const Svg = require("./svg");
|
|
6
|
+
const error = require("./error");
|
|
7
|
+
const Option = require("./option");
|
|
8
|
+
const is = require("oslllo-validator");
|
|
9
|
+
const Processor = require("./processor");
|
|
10
|
+
const { AUTO, FORMATS } = require("./constants");
|
|
11
|
+
|
|
12
|
+
const Svg2 = function (input) {
|
|
13
|
+
if (!(this instanceof Svg2)) {
|
|
14
|
+
return new Svg2(input);
|
|
15
|
+
}
|
|
16
|
+
input = this.check(input);
|
|
17
|
+
this.options = new Option();
|
|
18
|
+
this.input = {
|
|
19
|
+
string: input,
|
|
20
|
+
element: null,
|
|
21
|
+
};
|
|
22
|
+
this.output = {
|
|
23
|
+
file: undefined,
|
|
24
|
+
format: undefined,
|
|
25
|
+
resize: undefined,
|
|
26
|
+
extend: undefined,
|
|
27
|
+
background: undefined
|
|
28
|
+
};
|
|
29
|
+
this.jimp = jimp;
|
|
30
|
+
this.svg = new Svg(this);
|
|
31
|
+
this.processor = new Processor(this);
|
|
32
|
+
return this;
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
Svg2.prototype = {
|
|
36
|
+
check: function (input) {
|
|
37
|
+
if (arguments.length === 1 && !is.defined(input)) {
|
|
38
|
+
throw error.invalidParameterError(
|
|
39
|
+
"input",
|
|
40
|
+
"SVG string or SVG string in a buffer",
|
|
41
|
+
input
|
|
42
|
+
);
|
|
43
|
+
}
|
|
44
|
+
if (!is.buffer(input) && !is.string(input)) {
|
|
45
|
+
throw error.invalidParameterError(
|
|
46
|
+
"input",
|
|
47
|
+
"SVG string or SVG string in a buffer",
|
|
48
|
+
input
|
|
49
|
+
);
|
|
50
|
+
}
|
|
51
|
+
if (is.buffer(input)) {
|
|
52
|
+
input = Buffer.from(input).toString();
|
|
53
|
+
}
|
|
54
|
+
if (is.pathToFile(input)) {
|
|
55
|
+
input = fs.readFileSync(input, "utf-8");
|
|
56
|
+
}
|
|
57
|
+
if (!is.svg(input)) {
|
|
58
|
+
throw error.invalidParameterError("input", "valid SVG", `invalid SVG: ${input}`);
|
|
59
|
+
}
|
|
60
|
+
return input;
|
|
61
|
+
},
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
Svg2.AUTO = AUTO;
|
|
65
|
+
Svg2.BMP = FORMATS.bmp
|
|
66
|
+
Svg2.PNG = FORMATS.png
|
|
67
|
+
Svg2.TIFF = FORMATS.tiff
|
|
68
|
+
Svg2.JPEG = FORMATS.jpeg
|
|
69
|
+
|
|
70
|
+
module.exports = Svg2;
|
package/src/error.js
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Create an Error with a message relating to an invalid parameter.
|
|
5
|
+
*
|
|
6
|
+
* @param {string} name - parameter name.
|
|
7
|
+
* @param {string} expected - description of the type/value/range expected.
|
|
8
|
+
* @param {*} actual - the value received.
|
|
9
|
+
* @returns {Error} Containing the formatted message.
|
|
10
|
+
* @private
|
|
11
|
+
*/
|
|
12
|
+
const invalidParameterError = function (name, expected, actual) {
|
|
13
|
+
return new TypeError(
|
|
14
|
+
`Expected <${expected}> for [${name}] but received ${actual} of type <${typeof actual}>`
|
|
15
|
+
);
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
module.exports = {
|
|
19
|
+
invalidParameterError: invalidParameterError,
|
|
20
|
+
};
|
package/src/index.js
ADDED
package/src/option.js
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
const error = require("./error");
|
|
4
|
+
const is = require("oslllo-validator");
|
|
5
|
+
const constants = require("./constants");
|
|
6
|
+
|
|
7
|
+
const Option = function () {
|
|
8
|
+
this.data = {
|
|
9
|
+
main: { resolveWithObject: false },
|
|
10
|
+
png: { transparent: false },
|
|
11
|
+
uri: { base64: false, mime: constants.FORMATS.png },
|
|
12
|
+
extend: { top: 0, right: 0, bottom: 0, left: 0, background: "#ffffff" },
|
|
13
|
+
background: { color: "#ffffff" }
|
|
14
|
+
};
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
Option.prototype = {
|
|
18
|
+
get: function (setting) {
|
|
19
|
+
if (!is.defined(setting) || typeof setting !== "string") {
|
|
20
|
+
throw error.invalidParameterError("setting", "string", setting);
|
|
21
|
+
}
|
|
22
|
+
var expected = Object.keys(this.data);
|
|
23
|
+
if (!expected.includes(setting)) {
|
|
24
|
+
throw error.invalidParameterError("setting", expected.toString(), setting);
|
|
25
|
+
}
|
|
26
|
+
return this.data[setting];
|
|
27
|
+
},
|
|
28
|
+
update: function (setting, options) {
|
|
29
|
+
if (options == undefined || !is.object(options)) {
|
|
30
|
+
throw error.invalidParameterError("options", "object", options);
|
|
31
|
+
}
|
|
32
|
+
if (Object.keys(options).length === 0) {
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
var preset = this.get(setting);
|
|
36
|
+
for (var option in options) {
|
|
37
|
+
if (is.defined(preset[option])) {
|
|
38
|
+
this.data[setting][option] = options[option];
|
|
39
|
+
} else {
|
|
40
|
+
var expected = Object.keys(preset);
|
|
41
|
+
throw error.invalidParameterError(
|
|
42
|
+
"png",
|
|
43
|
+
`[${expected.toString()}]`,
|
|
44
|
+
option
|
|
45
|
+
);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
},
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
module.exports = Option;
|
package/src/output.js
ADDED
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
const fs = require("fs");
|
|
4
|
+
const jimp = require("jimp");
|
|
5
|
+
const error = require("./error");
|
|
6
|
+
const domino = require("domino");
|
|
7
|
+
const is = require("oslllo-validator");
|
|
8
|
+
const constants = require("./constants");
|
|
9
|
+
|
|
10
|
+
const formats = constants.FORMATS;
|
|
11
|
+
|
|
12
|
+
function png(options = {}) {
|
|
13
|
+
this.options.update("png", options);
|
|
14
|
+
options = this.options.get("png");
|
|
15
|
+
this.output.format = formats.png;
|
|
16
|
+
return this;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
function jpeg() {
|
|
20
|
+
this.output.format = formats.jpeg;
|
|
21
|
+
return this;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
function tiff() {
|
|
25
|
+
this.output.format = formats.tiff;
|
|
26
|
+
return this;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
function bmp() {
|
|
30
|
+
this.output.format = formats.bmp;
|
|
31
|
+
return this;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
function _getDocument(input) {
|
|
35
|
+
const document = domino.createDocument(input, true);
|
|
36
|
+
return document;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
function toElement(input) {
|
|
40
|
+
input = input ? input : this.svg.html();
|
|
41
|
+
input = this.check(input);
|
|
42
|
+
return _getDocument(input).getElementsByTagName("svg")[0];
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
function toUri(options = {}, callback) {
|
|
46
|
+
if (arguments.length === 1 && is.fn(options)) {
|
|
47
|
+
callback = options;
|
|
48
|
+
} else {
|
|
49
|
+
this.options.update("uri", options);
|
|
50
|
+
}
|
|
51
|
+
options = this.options.get("uri");
|
|
52
|
+
var mime = options.mime;
|
|
53
|
+
var base64 = options.base64;
|
|
54
|
+
var svg = this.svg.html();
|
|
55
|
+
var png = this.svg.png(svg);
|
|
56
|
+
|
|
57
|
+
async function generateDataUri() {
|
|
58
|
+
const buffer = await png;
|
|
59
|
+
var image = await jimp.read(buffer);
|
|
60
|
+
var uri = await image.getBase64Async(mime);
|
|
61
|
+
if (base64) {
|
|
62
|
+
uri = uri.replace(new RegExp(`^data:${mime};base64,`), "");
|
|
63
|
+
}
|
|
64
|
+
return uri;
|
|
65
|
+
}
|
|
66
|
+
if (is.defined(callback)) {
|
|
67
|
+
if (!is.fn(callback)) {
|
|
68
|
+
throw error.invalidParameterError("callback", "function", callback);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
generateDataUri()
|
|
72
|
+
.then((uri) => {
|
|
73
|
+
callback(null, uri);
|
|
74
|
+
})
|
|
75
|
+
.catch((error) => {
|
|
76
|
+
callback(error);
|
|
77
|
+
});
|
|
78
|
+
} else {
|
|
79
|
+
return generateDataUri();
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
function toBuffer(callback) {
|
|
84
|
+
if (is.defined(callback) && !is.fn(callback) && callback !== undefined) {
|
|
85
|
+
throw error.invalidParameterError("callback", "function", callback);
|
|
86
|
+
}
|
|
87
|
+
return this.processor.pipeline(callback);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
function toFile(destination, callback) {
|
|
91
|
+
if (!destination || destination.length === 0 || typeof destination !== "string") {
|
|
92
|
+
const err = error.invalidParameterError("destination", "string", destination);
|
|
93
|
+
if (is.fn(callback)) {
|
|
94
|
+
callback(err);
|
|
95
|
+
} else {
|
|
96
|
+
return Promise.reject(err);
|
|
97
|
+
}
|
|
98
|
+
} else {
|
|
99
|
+
if (callback || is.defined(callback)) {
|
|
100
|
+
if (is.fn(callback)) {
|
|
101
|
+
this.processor.pipeline((err, buffer) => {
|
|
102
|
+
fs.writeFile(destination, buffer, callback);
|
|
103
|
+
});
|
|
104
|
+
} else {
|
|
105
|
+
throw error.invalidParameterError("callback", "function", callback);
|
|
106
|
+
}
|
|
107
|
+
} else {
|
|
108
|
+
return new Promise((resolve, reject) => {
|
|
109
|
+
var error;
|
|
110
|
+
this.processor.pipeline((err, buffer) => {
|
|
111
|
+
if (err) {
|
|
112
|
+
reject(err);
|
|
113
|
+
return;
|
|
114
|
+
}
|
|
115
|
+
fs.writeFile(destination, buffer, (err) => {
|
|
116
|
+
err ? reject(err) : resolve();
|
|
117
|
+
});
|
|
118
|
+
});
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
module.exports = function (Svg2) {
|
|
125
|
+
Object.assign(Svg2.prototype, {
|
|
126
|
+
png: png,
|
|
127
|
+
bmp: bmp,
|
|
128
|
+
jpeg: jpeg,
|
|
129
|
+
tiff: tiff,
|
|
130
|
+
toUri: toUri,
|
|
131
|
+
toFile: toFile,
|
|
132
|
+
toBuffer: toBuffer,
|
|
133
|
+
toElement: toElement,
|
|
134
|
+
});
|
|
135
|
+
};
|
package/src/processor.js
ADDED
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
const jimp = require("jimp");
|
|
4
|
+
const is = require("oslllo-validator");
|
|
5
|
+
const constants = require("./constants");
|
|
6
|
+
|
|
7
|
+
const formats = constants.FORMATS;
|
|
8
|
+
|
|
9
|
+
function Processor(instance) {
|
|
10
|
+
this.instance = instance;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
Processor.prototype = {
|
|
14
|
+
pipeline: function (callback) {
|
|
15
|
+
var format = this.instance.output.format;
|
|
16
|
+
if (!format || !is.defined(format)) {
|
|
17
|
+
const err = new Error(`Output format was not set.`);
|
|
18
|
+
callback(err);
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
var i = this.instance;
|
|
22
|
+
if (is.fn(callback)) {
|
|
23
|
+
this.process((err, buffer) => {
|
|
24
|
+
i.output.file = buffer;
|
|
25
|
+
callback(err, buffer);
|
|
26
|
+
});
|
|
27
|
+
} else {
|
|
28
|
+
return new Promise((resolve, reject) => {
|
|
29
|
+
this.process((err, buffer) => {
|
|
30
|
+
i.output.file = buffer;
|
|
31
|
+
err ? reject(err) : resolve(buffer);
|
|
32
|
+
});
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
},
|
|
36
|
+
process: function (callback) {
|
|
37
|
+
var i = this.instance;
|
|
38
|
+
i.svg
|
|
39
|
+
.png(i.svg.html())
|
|
40
|
+
.then(async (png) => {
|
|
41
|
+
png = await jimp.read(png);
|
|
42
|
+
/**
|
|
43
|
+
* @ignore
|
|
44
|
+
* @description - Because only pngs can be transparent
|
|
45
|
+
* */
|
|
46
|
+
if (!i.options.get("png").transparent || i.output.format !== formats.png) {
|
|
47
|
+
var dimensions = i.svg.dimensions();
|
|
48
|
+
png = await this.background(png, dimensions);
|
|
49
|
+
}
|
|
50
|
+
for (var format in formats) {
|
|
51
|
+
if (formats[format] === i.output.format) {
|
|
52
|
+
png.getBuffer(formats[format], callback);
|
|
53
|
+
break;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
})
|
|
57
|
+
.catch((error) => {
|
|
58
|
+
callback(error);
|
|
59
|
+
});
|
|
60
|
+
},
|
|
61
|
+
blank: function (width = jimp.AUTO, height = jimp.AUTO, background) {
|
|
62
|
+
if (!background) {
|
|
63
|
+
background = this.instance.options.get("background").color;
|
|
64
|
+
}
|
|
65
|
+
return new jimp(width, height, background);
|
|
66
|
+
},
|
|
67
|
+
background: async function (image, dimensions) {
|
|
68
|
+
var { width, height } = dimensions;
|
|
69
|
+
|
|
70
|
+
var x, y;
|
|
71
|
+
x = y = 0;
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* @ignore
|
|
75
|
+
* @description - Set initial background
|
|
76
|
+
*/
|
|
77
|
+
var background = await this.blank(width, height);
|
|
78
|
+
image = background.composite(image, x, y);
|
|
79
|
+
|
|
80
|
+
if (this.instance.output.extend) {
|
|
81
|
+
var options = this.instance.options.get("extend");
|
|
82
|
+
|
|
83
|
+
var extended = {
|
|
84
|
+
background: options.background,
|
|
85
|
+
height: options.top + options.bottom + height,
|
|
86
|
+
width: options.left + options.right + width,
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
if (options.left) {
|
|
90
|
+
x = x + options.left;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
if (options.top) {
|
|
94
|
+
y = y + options.top;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
extended.image = await this.blank(extended.width, extended.height, extended.background);
|
|
98
|
+
|
|
99
|
+
image = extended.image.composite(image, x, y);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
return image;
|
|
103
|
+
},
|
|
104
|
+
};
|
|
105
|
+
|
|
106
|
+
module.exports = Processor;
|
package/src/resize.js
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
const error = require("./error");
|
|
4
|
+
const is = require("oslllo-validator");
|
|
5
|
+
|
|
6
|
+
function extend(options) {
|
|
7
|
+
if (is.object(options)) {
|
|
8
|
+
this.options.update("extend", options);
|
|
9
|
+
} else if (is.number(options)) {
|
|
10
|
+
var sides = new Object();
|
|
11
|
+
["top", "right", "bottom", "left"].forEach((side) => {
|
|
12
|
+
sides[side] = options;
|
|
13
|
+
});
|
|
14
|
+
this.options.update("extend", sides);
|
|
15
|
+
} else {
|
|
16
|
+
throw error.invalidParameterError("options", "object or number", options);
|
|
17
|
+
}
|
|
18
|
+
options = this.options.get("extend");
|
|
19
|
+
this.output.extend = options;
|
|
20
|
+
return this;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
module.exports = function (Svg2) {
|
|
24
|
+
Object.assign(Svg2.prototype, {
|
|
25
|
+
extend: extend,
|
|
26
|
+
});
|
|
27
|
+
};
|
package/src/svg.js
ADDED
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
const Svg2 = require("..");
|
|
4
|
+
const error = require("./error");
|
|
5
|
+
const is = require("oslllo-validator");
|
|
6
|
+
const constants = require("./constants");
|
|
7
|
+
const { renderAsync } = require("@ohos-ports/resvg-resvg-js");
|
|
8
|
+
const Svg = function (instance) {
|
|
9
|
+
this.instance = instance;
|
|
10
|
+
this.update(instance.toElement(instance.input.string), true);
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
Svg.prototype = {
|
|
14
|
+
update: function (svg, isElement = false) {
|
|
15
|
+
if (isElement) {
|
|
16
|
+
if (svg.constructor.name !== "SVGSVGElement") {
|
|
17
|
+
throw error.invalidParameterError("svg", "SVGSVGElement", svg);
|
|
18
|
+
}
|
|
19
|
+
} else {
|
|
20
|
+
svg = this.instance.check(svg);
|
|
21
|
+
svg = this.instance.toElement(svg);
|
|
22
|
+
}
|
|
23
|
+
this.instance.input.element = svg;
|
|
24
|
+
this.instance.input.string = svg.outerHTML;
|
|
25
|
+
return this.instance;
|
|
26
|
+
},
|
|
27
|
+
resize: function (input) {
|
|
28
|
+
if (!is.defined(input) || (input.constructor.name !== "Object" && !is.number(input))) {
|
|
29
|
+
throw error.invalidParameterError("input", "object or number", input);
|
|
30
|
+
}
|
|
31
|
+
var svg = this.element();
|
|
32
|
+
var current = this.dimensions();
|
|
33
|
+
var output = {
|
|
34
|
+
scale: 0,
|
|
35
|
+
width: undefined,
|
|
36
|
+
height: undefined,
|
|
37
|
+
};
|
|
38
|
+
function set(dimension) {
|
|
39
|
+
var opposite = dimension == "height" ? "width" : "height";
|
|
40
|
+
output[dimension] = input[dimension];
|
|
41
|
+
if (input[opposite] === constants.AUTO) {
|
|
42
|
+
output[opposite] = output[opposite] = (input[dimension] / current[dimension]) * current[opposite];
|
|
43
|
+
} else {
|
|
44
|
+
output[opposite] = current[opposite];
|
|
45
|
+
}
|
|
46
|
+
return output;
|
|
47
|
+
}
|
|
48
|
+
if (is.number(input)) {
|
|
49
|
+
output.width = current.width * input;
|
|
50
|
+
output.height = current.height * input;
|
|
51
|
+
output.scale = input;
|
|
52
|
+
} else {
|
|
53
|
+
if (
|
|
54
|
+
is.defined(input.width) &&
|
|
55
|
+
input.width !== constants.AUTO &&
|
|
56
|
+
is.defined(input.height) &&
|
|
57
|
+
input.height !== constants.AUTO
|
|
58
|
+
) {
|
|
59
|
+
output.width = input.width;
|
|
60
|
+
output.height = input.height;
|
|
61
|
+
} else if (is.defined(input.width) && input.width !== constants.AUTO) {
|
|
62
|
+
output = set("width");
|
|
63
|
+
} else if (is.defined(input.height) && input.height !== constants.AUTO) {
|
|
64
|
+
output = set("height");
|
|
65
|
+
} else {
|
|
66
|
+
throw error.invalidParameterError("input", "width or height in object", input);
|
|
67
|
+
}
|
|
68
|
+
output.scale = (output.width / current.width + output.height / current.height) / 2;
|
|
69
|
+
}
|
|
70
|
+
svg.setAttribute("width", output.width);
|
|
71
|
+
svg.setAttribute("height", output.height);
|
|
72
|
+
this.update(svg, true);
|
|
73
|
+
this.instance.output.resize = output;
|
|
74
|
+
return this.instance;
|
|
75
|
+
},
|
|
76
|
+
html: function () {
|
|
77
|
+
return this.instance.input.string;
|
|
78
|
+
},
|
|
79
|
+
png: async function (svg) {
|
|
80
|
+
const opts = {
|
|
81
|
+
font: {
|
|
82
|
+
loadSystemFonts: true, // It will be faster to disable loading system fonts.
|
|
83
|
+
},
|
|
84
|
+
};
|
|
85
|
+
const resvg = await renderAsync(svg, opts);
|
|
86
|
+
const pngBuffer = resvg.asPng();
|
|
87
|
+
|
|
88
|
+
return pngBuffer;
|
|
89
|
+
},
|
|
90
|
+
element: function () {
|
|
91
|
+
return this.instance.input.element;
|
|
92
|
+
},
|
|
93
|
+
dimensionToPx: function (input) {
|
|
94
|
+
if (!input || (typeof input != "string" && typeof input != "number")) {
|
|
95
|
+
throw error.invalidParameterError("input", "string with dimension or number", input);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
function round(input) {
|
|
99
|
+
return Math.round((input + Number.EPSILON) * 100) / 100;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
var units = ["rem", "px", "em", "ex", "ch", "cm", "mm", "q", "in", "pc", "pt"];
|
|
103
|
+
var convert = false;
|
|
104
|
+
for (var i = 0; i < units.length; i++) {
|
|
105
|
+
var unit = units[i];
|
|
106
|
+
convert = typeof input == "string" && input.search(unit) !== -1;
|
|
107
|
+
if (convert) {
|
|
108
|
+
input = input.replace(unit, "");
|
|
109
|
+
const cm = 96 / 2.54;
|
|
110
|
+
const inch = 2.54 * cm;
|
|
111
|
+
switch (unit.toLowerCase()) {
|
|
112
|
+
case "px":
|
|
113
|
+
break;
|
|
114
|
+
case "em":
|
|
115
|
+
case "rem":
|
|
116
|
+
input = input * 16; // we can get away with this because we use jsdom.
|
|
117
|
+
break;
|
|
118
|
+
case "ex":
|
|
119
|
+
input = round(input * 7.156);
|
|
120
|
+
break;
|
|
121
|
+
case "ch":
|
|
122
|
+
input = input * 8;
|
|
123
|
+
break;
|
|
124
|
+
case "cm":
|
|
125
|
+
input = input * cm;
|
|
126
|
+
break;
|
|
127
|
+
case "mm":
|
|
128
|
+
input = round(input * ((1 / 10) * cm));
|
|
129
|
+
break;
|
|
130
|
+
case "q":
|
|
131
|
+
input = input * ((1 / 40) * cm);
|
|
132
|
+
break;
|
|
133
|
+
case "in":
|
|
134
|
+
input = input * inch;
|
|
135
|
+
break;
|
|
136
|
+
case "pc":
|
|
137
|
+
input = input * ((1 / 6) * inch);
|
|
138
|
+
break;
|
|
139
|
+
case "pt":
|
|
140
|
+
input = input * ((1 / 72) * inch);
|
|
141
|
+
break;
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
var dimension = Number(input);
|
|
146
|
+
if (isNaN(dimension)) {
|
|
147
|
+
throw error.invalidParameterError("input", "a valid dimension i.e 20px, 20rem, 20em or 20", input);
|
|
148
|
+
}
|
|
149
|
+
return dimension;
|
|
150
|
+
},
|
|
151
|
+
viewBox: function (svg) {
|
|
152
|
+
if (!svg.hasAttribute("viewBox")) {
|
|
153
|
+
throw error.invalidParameterError(
|
|
154
|
+
"SVG dimension",
|
|
155
|
+
"height/width and viewBox attributes to be set",
|
|
156
|
+
this.instance.svg.html()
|
|
157
|
+
);
|
|
158
|
+
}
|
|
159
|
+
var viewBox = svg.getAttribute("viewBox").split(" ");
|
|
160
|
+
return {
|
|
161
|
+
"min-x": Number(viewBox[0]),
|
|
162
|
+
"min-y": Number(viewBox[1]),
|
|
163
|
+
width: Number(viewBox[2]),
|
|
164
|
+
height: Number(viewBox[3]),
|
|
165
|
+
};
|
|
166
|
+
},
|
|
167
|
+
dimensions: function () {
|
|
168
|
+
var svg = this.element();
|
|
169
|
+
var dimension = {
|
|
170
|
+
names: ["width", "height"],
|
|
171
|
+
data: { width: 0, height: 0 },
|
|
172
|
+
};
|
|
173
|
+
var dn = dimension.names;
|
|
174
|
+
var dd = dimension.data;
|
|
175
|
+
if (svg.hasAttribute(dn[0]) && svg.hasAttribute(dn[1])) {
|
|
176
|
+
var width = svg.getAttribute(dn[0]);
|
|
177
|
+
var height = svg.getAttribute(dn[1]);
|
|
178
|
+
if (!width.includes("%") && !width.includes("vw") && !height.includes("%") && !height.includes("vh")) {
|
|
179
|
+
for (var i = 0; i < dn.length; i++) {
|
|
180
|
+
var name = dn[i];
|
|
181
|
+
switch (name) {
|
|
182
|
+
case "width":
|
|
183
|
+
dd.width = this.dimensionToPx(width);
|
|
184
|
+
break;
|
|
185
|
+
case "height":
|
|
186
|
+
dd.height = this.dimensionToPx(height);
|
|
187
|
+
break;
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
} else {
|
|
191
|
+
var viewbox = this.viewBox(svg);
|
|
192
|
+
dd.width = viewbox.width;
|
|
193
|
+
dd.height = viewbox.height;
|
|
194
|
+
}
|
|
195
|
+
} else {
|
|
196
|
+
var viewbox = this.viewBox(svg);
|
|
197
|
+
dd.width = viewbox.width;
|
|
198
|
+
dd.height = viewbox.height;
|
|
199
|
+
}
|
|
200
|
+
return dd;
|
|
201
|
+
},
|
|
202
|
+
};
|
|
203
|
+
|
|
204
|
+
module.exports = Svg;
|