UNPKG

5.13 kBJavaScriptView Raw
1
2const { db } = require('../db/db');
3const { style, fsw } = require('@sutton-signwriting/core');
4const fs = require('fs');
5
6/**
7 * Function that creates an SVG image from an FSW sign with an optional style string
8 * @function fsw.signSvg
9 * @param {string} fswSign - an FSW sign with optional style string
10 * @param {function} callback - a callback function with error and result parameters
11 * @example
12 * const callback = (error, result) => {
13 * if (error) {
14 * console.log(error)
15 * } else {
16 * console.log(result + " is '<svg...")
17 * }
18 * }
19 *
20 * fsw.signSvg('M525x535S2e748483x510S10011501x466S2e704510x500S10019476x475', callback )
21 */
22const signSvg = (fswSign, callback) => {
23 let parsed = fsw.parse.sign(fswSign);
24 const blank = '<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="1" height="1"></svg>';
25 if (parsed.spatials) {
26 const symbols = parsed.spatials.map((spatial) => spatial.symbol);
27 db.all(`select symkey, svg, width, height from symbol where symkey in ("${symbols.join('","')}")`, (err, res) => {
28 if (err) {
29 callback(err, res);
30 } else {
31 if (!res) {
32 callback(err, blank)
33 } else {
34 const symbols = res.reduce((obj, row) => {
35 obj[row.symkey] = row
36 return obj;
37 }, {})
38
39 let styling = style.parse(parsed.style);
40
41 if (styling.detailsym) {
42 styling.detailsym.forEach(sym => {
43 parsed.spatials[sym.index - 1].detail = sym.detail;
44 })
45 }
46
47 let x1 = Math.min(...parsed.spatials.map(spatial => spatial.coord[0]));
48 let y1 = Math.min(...parsed.spatials.map(spatial => spatial.coord[1]));
49 let x2 = parsed.max[0];
50 let y2 = parsed.max[1];
51
52 if (styling.zoomsym) {
53 styling.zoomsym.forEach(sym => {
54 parsed.spatials[sym.index - 1].zoom = sym.zoom;
55 if (sym.offset) {
56 parsed.spatials[sym.index - 1].coord[0] += sym.offset[0];
57 parsed.spatials[sym.index - 1].coord[1] += sym.offset[1];
58 }
59 x2 = Math.max(x2, (parsed.spatials[sym.index - 1].coord[0] + (symbols[parsed.spatials[sym.index - 1].symbol].width * sym.zoom)));
60 y2 = Math.max(y2, (parsed.spatials[sym.index - 1].coord[1] + (symbols[parsed.spatials[sym.index - 1].symbol].height * sym.zoom)));
61 })
62 }
63
64 let classes = '';
65 if (styling.classes) {
66 classes = ` class="${styling.classes}"`
67 }
68 let id = '';
69 if (styling.id) {
70 id = ` id="${styling.id}"`
71 }
72
73 let background = '';
74 if (styling.padding) {
75 x1 -= styling.padding;
76 y1 -= styling.padding;
77 x2 += styling.padding;
78 y2 += styling.padding;
79 }
80 if (styling.background) {
81 background = `\n <rect x="${x1}" y="${y1}" width="${x2 - x1}" height="${y2 - y1}" style="fill:${styling.background};" />`
82 }
83
84 let sizing = '';
85 if (styling.zoom != 'x') {
86 sizing = ` width="${(x2 - x1) * (styling.zoom ? styling.zoom : 1)}" height="${(y2 - y1) * (styling.zoom ? styling.zoom : 1)}"`;
87 }
88
89 let svg = `<svg${classes}${id} version="1.1" xmlns="http://www.w3.org/2000/svg"${sizing} viewBox="${x1} ${y1} ${(x2 - x1)} ${(y2 - y1)}">
90 <text font-size="0">${fswSign}</text>${background}`
91
92 const line = styling.detail && styling.detail[0];
93 const fill = styling.detail && styling.detail[1];
94
95 svg += '\n' + parsed.spatials.map(spatial => {
96 let svg = symbols[spatial.symbol] ? symbols[spatial.symbol].svg : '';
97
98 let symLine = line;
99 if (spatial.detail) {
100 symLine = spatial.detail[0];
101 } else if (styling.colorize) {
102 symLine = fsw.colorize(spatial.symbol);
103 }
104 if (symLine) {
105 svg = svg.replace(/class="sym-line"/, `class="sym-line" fill="${symLine}"`);
106 }
107
108 let symFill = fill;
109 if (spatial.detail && spatial.detail[1]) {
110 symFill = spatial.detail[1];
111 }
112 if (symFill) {
113 svg = svg.replace(/class="sym-fill" fill="#ffffff"/, `class="sym-fill" fill="${symFill}"`);
114 }
115
116 if (spatial.zoom) {
117 svg = `<g transform="scale(${spatial.zoom})">${svg}</g>`;
118 }
119
120 return ` <svg x="${spatial.coord[0]}" y="${spatial.coord[1]}">${svg}</svg>`;
121
122 }).join('\n');
123
124 svg += '\n</svg>';
125 callback(null, svg);
126 }
127 }
128 })
129 } else {
130 callback(null, blank);
131 }
132}
133
134if (require.main === module) {
135 signSvg(process.argv[2], (err, res) => {
136 if (process.argv[3]) {
137 fs.writeFileSync(process.argv[3], res)
138 } else {
139 console.log(err || res);
140 }
141 })
142} else {
143 module.exports = { signSvg }
144}