1 |
|
2 | const { svg2png } = require('../common/svg2png');
|
3 | const { columnSvg } = require('./fsw-column-svg');
|
4 | const fs = require('fs');
|
5 |
|
6 | /**
|
7 | * Function that creates an PNG image for a column of FSW
|
8 | * @function fsw.columnPng
|
9 | * @param {ColumnData} fswColumn - an array of objects with information about FSW signs and punctuation
|
10 | * @param {ColumnOptions} options - an object of column options
|
11 | * @returns {ArrayBuffer} column png
|
12 | * @example
|
13 | * const columnData = [
|
14 | * {"x":56,"y":20,"minX":481,"minY":471,"width":37,"height":58,"lane":0,"padding":0,"segment":"sign","text":"AS14c20S27106M518x529S14c20481x471S27106503x489","zoom":1},
|
15 | * {"x":57,"y":118,"minX":482,"minY":468,"width":36,"height":65,"lane":0,"padding":0,"segment":"sign","text":"AS18701S1870aS2e734S20500M518x533S1870a489x515S18701482x490S20500508x496S2e734500x468","zoom":1},
|
16 | * {"x":39,"y":203,"minX":464,"minY":496,"width":72,"height":8,"lane":0,"padding":0,"segment":"symbol","text":"S38800464x496","zoom":1}
|
17 | * ];
|
18 | * const columnOptions = {"height": 250, "width": 150};
|
19 | * @example
|
20 | * // using promise.then
|
21 | * fsw.columnPng(columnData, columnOptions).then( png => {
|
22 | * console.log(png)
|
23 | * })
|
24 | * @example
|
25 | * // using async/await
|
26 | * const png = await fsw.columnPng(columnData, columnOptions)
|
27 | */
|
28 | const columnPng = async (fswColumn, options) => {
|
29 | let svg = await columnSvg(fswColumn, options);
|
30 | svg = svg.replace(/<text.*text>/g, "");
|
31 | const png = await svg2png(svg);
|
32 | return png;
|
33 | }
|
34 |
|
35 | /**
|
36 | * Function that creates a data url PNG image from an FSW sign with an optional style string
|
37 | * @function fsw.columnPngDataUrl
|
38 | * @param {string} fswSign - an FSW sign with optional style string
|
39 | * @returns {string} column png
|
40 | * @example
|
41 | * const columnData = [
|
42 | * {"x":56,"y":20,"minX":481,"minY":471,"width":37,"height":58,"lane":0,"padding":0,"segment":"sign","text":"AS14c20S27106M518x529S14c20481x471S27106503x489","zoom":1},
|
43 | * {"x":57,"y":118,"minX":482,"minY":468,"width":36,"height":65,"lane":0,"padding":0,"segment":"sign","text":"AS18701S1870aS2e734S20500M518x533S1870a489x515S18701482x490S20500508x496S2e734500x468","zoom":1},
|
44 | * {"x":39,"y":203,"minX":464,"minY":496,"width":72,"height":8,"lane":0,"padding":0,"segment":"symbol","text":"S38800464x496","zoom":1}
|
45 | * ];
|
46 | * const columnOptions = {"height": 250, "width": 150};
|
47 | * @example
|
48 | * // using promise.then
|
49 | * fsw.columnPngDataUrl(columnData, columnOptions).then( png => {
|
50 | * console.log(png)
|
51 | * })
|
52 | * @example
|
53 | * // using async/await
|
54 | * const png = await fsw.columnPngDataUrl(columnData, columnOptions)
|
55 | */
|
56 | const columnPngDataUrl = async (fswSign) => {
|
57 | const res = await columnPng(fswSign);
|
58 | return 'data:image/png;base64,' + res.toString('base64');
|
59 | }
|
60 |
|
61 | const parseArg = (val) => {
|
62 | try {
|
63 | return JSON.parse(val)
|
64 | } catch {
|
65 | return undefined
|
66 | }
|
67 | }
|
68 |
|
69 | const helpArgs = () => {
|
70 | console.log("FSW Column PNG\n")
|
71 | console.log("Usage: node fsw/fsw-column-png.js ColumnData [OutputFile] [Arguments]\n");
|
72 | console.log("ColumnData");
|
73 | console.log(" https://www.sutton-signwriting.io/core/#columndata\n");
|
74 | console.log("StyleObject");
|
75 | console.log(" https://www.sutton-signwriting.io/core/#styleobject\n");
|
76 | console.log("Arguments for ColumnOptions used to create ColumnData");
|
77 | console.log("--height the height of the column");
|
78 | console.log("--width the width of the column");
|
79 | console.log("--offset the lane offset for left and right lanes");
|
80 | console.log("--pad amount of padding before and after signs as well as at top, left, and right of column");
|
81 | console.log("--margin amount of space at bottom of column that is not available");
|
82 | console.log("--dynamic enables variable width column");
|
83 | console.log("--background background color for column");
|
84 | console.log("--style an object of style options for signs");
|
85 | console.log("--puncuation an object of punctuation options");
|
86 | process.exit(1);
|
87 | }
|
88 |
|
89 | if (require.main === module) {
|
90 | const args = require('minimist')(process.argv.slice(2));
|
91 | const segments = parseArg(args._[0]);
|
92 | const file = args._[1];
|
93 | if (!segments || args.help) helpArgs();
|
94 |
|
95 | args.style = parseArg(args["style"]);
|
96 | args.punctuation = parseArg(args["punctuation"]);
|
97 | args.detail = parseArg(args["detail"]);
|
98 |
|
99 | args.options = parseArg(args["options"]);
|
100 | args.options = (typeof args.options == 'object')?args.options:{};
|
101 | Object.keys(args).map((key)=>{
|
102 | switch (key) {
|
103 | case '_':
|
104 | case 'options':
|
105 | break;
|
106 | default:
|
107 | args.options[key] = args[key]
|
108 | }
|
109 | })
|
110 | if (file) {
|
111 | columnPng(segments,args.options).then( png => {
|
112 | fs.writeFileSync(file, png);
|
113 | })
|
114 | } else {
|
115 | columnPngDataUrl(segments,args.options).then( png => {
|
116 | console.log(png);
|
117 | })
|
118 | }
|
119 | } else {
|
120 | module.exports = { columnPng, columnPngDataUrl }
|
121 | }
|