86 lines
2.3 KiB
JavaScript
86 lines
2.3 KiB
JavaScript
|
const backgroundWhite = '\x1b[47m'
|
||
|
const backgroundBlack = '\x1b[40m'
|
||
|
const foregroundWhite = '\x1b[37m'
|
||
|
const foregroundBlack = '\x1b[30m'
|
||
|
const reset = '\x1b[0m'
|
||
|
const lineSetupNormal = backgroundWhite + foregroundBlack // setup colors
|
||
|
const lineSetupInverse = backgroundBlack + foregroundWhite // setup colors
|
||
|
|
||
|
const createPalette = function (lineSetup, foregroundWhite, foregroundBlack) {
|
||
|
return {
|
||
|
// 1 ... white, 2 ... black, 0 ... transparent (default)
|
||
|
|
||
|
'00': reset + ' ' + lineSetup,
|
||
|
'01': reset + foregroundWhite + '▄' + lineSetup,
|
||
|
'02': reset + foregroundBlack + '▄' + lineSetup,
|
||
|
10: reset + foregroundWhite + '▀' + lineSetup,
|
||
|
11: ' ',
|
||
|
12: '▄',
|
||
|
20: reset + foregroundBlack + '▀' + lineSetup,
|
||
|
21: '▀',
|
||
|
22: '█'
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Returns code for QR pixel
|
||
|
* @param {boolean[][]} modules
|
||
|
* @param {number} size
|
||
|
* @param {number} x
|
||
|
* @param {number} y
|
||
|
* @return {'0' | '1' | '2'}
|
||
|
*/
|
||
|
const mkCodePixel = function (modules, size, x, y) {
|
||
|
const sizePlus = size + 1
|
||
|
if ((x >= sizePlus) || (y >= sizePlus) || (y < -1) || (x < -1)) return '0'
|
||
|
if ((x >= size) || (y >= size) || (y < 0) || (x < 0)) return '1'
|
||
|
const idx = (y * size) + x
|
||
|
return modules[idx] ? '2' : '1'
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Returns code for four QR pixels. Suitable as key in palette.
|
||
|
* @param {boolean[][]} modules
|
||
|
* @param {number} size
|
||
|
* @param {number} x
|
||
|
* @param {number} y
|
||
|
* @return {keyof palette}
|
||
|
*/
|
||
|
const mkCode = function (modules, size, x, y) {
|
||
|
return (
|
||
|
mkCodePixel(modules, size, x, y) +
|
||
|
mkCodePixel(modules, size, x, y + 1)
|
||
|
)
|
||
|
}
|
||
|
|
||
|
exports.render = function (qrData, options, cb) {
|
||
|
const size = qrData.modules.size
|
||
|
const data = qrData.modules.data
|
||
|
|
||
|
const inverse = !!(options && options.inverse)
|
||
|
const lineSetup = options && options.inverse ? lineSetupInverse : lineSetupNormal
|
||
|
const white = inverse ? foregroundBlack : foregroundWhite
|
||
|
const black = inverse ? foregroundWhite : foregroundBlack
|
||
|
|
||
|
const palette = createPalette(lineSetup, white, black)
|
||
|
const newLine = reset + '\n' + lineSetup
|
||
|
|
||
|
let output = lineSetup // setup colors
|
||
|
|
||
|
for (let y = -1; y < size + 1; y += 2) {
|
||
|
for (let x = -1; x < size; x++) {
|
||
|
output += palette[mkCode(data, size, x, y)]
|
||
|
}
|
||
|
|
||
|
output += palette[mkCode(data, size, size, y)] + newLine
|
||
|
}
|
||
|
|
||
|
output += reset
|
||
|
|
||
|
if (typeof cb === 'function') {
|
||
|
cb(null, output)
|
||
|
}
|
||
|
|
||
|
return output
|
||
|
}
|