1 |
|
2 | const fs = require('fs');
|
3 | const { promisify } = require('util');
|
4 | const glob = require('glob');
|
5 | const xml2js = require('xml2js');
|
6 |
|
7 | const SVGIcons2SVGFontStream = require('svgicons2svgfont');
|
8 | const SVGIconsDirStream = require('svgicons2svgfont/src/iconsdir');
|
9 |
|
10 | const svg2ttf = require('svg2ttf');
|
11 |
|
12 | const readFileAsync = promisify(fs.readFile);
|
13 | const writeFileAsync = promisify(fs.writeFile);
|
14 |
|
15 | function makeSvgFont(fontName, svgs, svgFontPath) {
|
16 | const files = glob.sync(svgs);
|
17 | const options = {
|
18 |
|
19 |
|
20 |
|
21 | fontHeight: 1000,
|
22 | normalize: true,
|
23 | };
|
24 |
|
25 | return new Promise((resolve, reject) => {
|
26 | new SVGIconsDirStream(files, {})
|
27 | .pipe(
|
28 | new SVGIcons2SVGFontStream({
|
29 | ...options,
|
30 | fontName,
|
31 | })
|
32 | )
|
33 | .pipe(fs.createWriteStream(svgFontPath))
|
34 | .on('finish', resolve)
|
35 | .on('error', reject);
|
36 | });
|
37 | }
|
38 |
|
39 | async function convertSvg2Ttf(svgFontPath, output) {
|
40 | const ttf = svg2ttf(await readFileAsync(svgFontPath, 'utf8'), {});
|
41 | await writeFileAsync(output, Buffer.from(ttf.buffer));
|
42 | }
|
43 |
|
44 | async function generateGlyphMap(svgFontPath, output) {
|
45 | const parser = new xml2js.Parser();
|
46 | const glyphMap = {};
|
47 | const data = await readFileAsync(svgFontPath);
|
48 |
|
49 | return new Promise((resolve, reject) => {
|
50 | parser.parseString(data, function(err, result) {
|
51 | if (err !== null) {
|
52 | reject(err);
|
53 | }
|
54 | if (!result) {
|
55 | console.error(`cannot parse ${svgFontPath}`);
|
56 | }
|
57 |
|
58 | const icons = result.svg.defs[0].font[0].glyph;
|
59 |
|
60 | icons.forEach(({ $: icon }) => {
|
61 | const name = icon['glyph-name'];
|
62 | const code = icon.unicode.charCodeAt(0);
|
63 | glyphMap[name] = code;
|
64 | });
|
65 |
|
66 | fs.writeFileSync(output, JSON.stringify(glyphMap, null, 2));
|
67 |
|
68 | resolve(glyphMap);
|
69 | });
|
70 | });
|
71 | }
|
72 |
|
73 | async function main() {
|
74 | const fontName = 'Ionicons';
|
75 |
|
76 |
|
77 | const svgFontPath = `./${fontName}.svg`;
|
78 | const glyphMapPath = `./glyphmaps/${fontName}.json`;
|
79 | const tffPath = `./Fonts/${fontName}.ttf`;
|
80 |
|
81 |
|
82 |
|
83 | await makeSvgFont(fontName, './Ioniconstmp/*.svg', svgFontPath);
|
84 |
|
85 | await Promise.all([
|
86 |
|
87 | generateGlyphMap(svgFontPath, glyphMapPath),
|
88 |
|
89 | convertSvg2Ttf(svgFontPath, tffPath),
|
90 | ]);
|
91 | console.log(`updated: ${tffPath} and ${glyphMapPath}`);
|
92 | }
|
93 |
|
94 | main();
|