* Split core lib into multiple files * Refactor data encoding methods * Refactor data masking process * Improve qr code generation process * Increase minimum required node version to 0.10 * Add linter * Add tests and tests coverage * Update travis config to fix compilation issues * Add examples folder * Add missing license tag in package.json * Update build script and add sourcemap support * Publish only strictly needed files on npm * Update readme
239 lines
5.7 KiB
JavaScript
239 lines
5.7 KiB
JavaScript
/*
|
|
*copyright Ryan Day 2012
|
|
*
|
|
* Licensed under the MIT license:
|
|
* http://www.opensource.org/licenses/mit-license.php
|
|
*
|
|
* this is the main server side application file for node-qrcode.
|
|
* these exports use serverside canvas api methods for file IO and buffers
|
|
*
|
|
*/
|
|
|
|
var QRCodeLib = require('./renderer/qrcode-draw')
|
|
var terminalRender = require('./renderer/terminal')
|
|
var svgRender = require('./renderer/svg')
|
|
var Canvas = require('canvas')
|
|
var fs = require('fs')
|
|
|
|
var QRCodeDraw = QRCodeLib.QRCodeDraw
|
|
|
|
// EXPORTS
|
|
|
|
//
|
|
// breaking change to 0.1 this used to be an instance. now it returns the constructor.
|
|
//
|
|
exports.QRCodeDraw = QRCodeDraw
|
|
|
|
//
|
|
// export error correct levels.
|
|
//
|
|
exports.errorCorrectLevels = QRCodeLib.QRErrorCorrectLevel
|
|
|
|
//
|
|
// export original canvas to be used with draw method, esp. Canvas.Image
|
|
//
|
|
exports.canvas = Canvas
|
|
|
|
/*
|
|
* provide an api to return the max characters allowed for given dimensions, and miniumum error correction level
|
|
* the qr code library will always use the maximum error correction level for the given numbar of chars constrained by size
|
|
*/
|
|
exports.getMaxChars = function (minErrorCorrectionLevel, width, moduleScale) {
|
|
// TODO THIS NEEDS TO WORK
|
|
console.log('this doesnt work yet. comming soon =)')
|
|
}
|
|
|
|
var parseOptions = function (options) {
|
|
var textKeys = {
|
|
'minimum': QRCodeLib.QRErrorCorrectLevel.L,
|
|
'medium': QRCodeLib.QRErrorCorrectLevel.M,
|
|
'high': QRCodeLib.QRErrorCorrectLevel.Q,
|
|
'max': QRCodeLib.QRErrorCorrectLevel.H
|
|
}
|
|
|
|
if (options.errorCorrectLevel) {
|
|
var ec = options.errorCorrectLevel
|
|
if (textKeys[ec]) {
|
|
options.errorCorrectLevel = textKeys[ec]
|
|
}
|
|
}
|
|
return options
|
|
}
|
|
|
|
// returns Canvas Object with qr code drawn on it
|
|
/*
|
|
* String text, optional Object options, Function callback
|
|
*/
|
|
var draw = exports.draw = function (text, options, cb) {
|
|
var args = Array.prototype.slice.call(arguments)
|
|
cb = args.pop()
|
|
if (typeof cb !== 'function') {
|
|
throw new TypeError('last argument must be a function')
|
|
}
|
|
|
|
text = args.shift()
|
|
options = args.shift() || {}
|
|
options = parseOptions(options)
|
|
|
|
// NOTE the width and height are determined from within the qr code lib and are not configurable from the outside yet
|
|
|
|
var drawInstance = new QRCodeDraw()
|
|
drawInstance.draw(new Canvas(200, 200), text, options, function (error, canvas, qrWidth) {
|
|
cb(error, canvas, qrWidth)
|
|
})
|
|
}
|
|
|
|
// returns data uri for drawn qrcode png
|
|
exports.toDataURL = exports.toDataURI = function (text, options, cb) {
|
|
if (typeof options === 'function') {
|
|
cb = options
|
|
options = {}
|
|
}
|
|
|
|
draw(text, options, function (error, canvas) {
|
|
if (error) {
|
|
cb(error)
|
|
} else {
|
|
canvas.toDataURL(cb)
|
|
}
|
|
})
|
|
}
|
|
|
|
// synchronous PNGStream
|
|
exports.toPNGStream = function (text, WSpath, options, cb) {
|
|
if (typeof options === 'function') {
|
|
cb = options
|
|
options = {}
|
|
}
|
|
|
|
var out = fs.createWriteStream(WSpath)
|
|
|
|
draw(text, options, function (error, canvas) {
|
|
var stream
|
|
if (error) {
|
|
cb(error, '')
|
|
} else {
|
|
stream = canvas.createPNGStream()
|
|
}
|
|
|
|
stream.pipe(out)
|
|
|
|
stream.on('end', function () {
|
|
cb(error, '')
|
|
})
|
|
|
|
stream.pipe(out)
|
|
})
|
|
|
|
return out
|
|
}
|
|
|
|
// returns bytes written to file
|
|
exports.save = function (path, text, options, cb) {
|
|
if (typeof options === 'function') {
|
|
cb = options
|
|
options = {}
|
|
}
|
|
|
|
var fileExt = path.slice((path.lastIndexOf('.') - 1 >>> 0) + 2).toLowerCase()
|
|
|
|
if (fileExt === 'svg') {
|
|
saveSvg(path, text, options, cb)
|
|
} else {
|
|
savePng(path, text, options, cb)
|
|
}
|
|
}
|
|
|
|
function savePng (path, text, options, cb) {
|
|
draw(text, options, function (error, canvas) {
|
|
if (error) {
|
|
throw new Error(error)
|
|
}
|
|
|
|
var fd
|
|
var buf
|
|
var fdAndBuf = function () {
|
|
fs.write(fd, buf, 0, buf.length, 0, function (fsErr, written) {
|
|
fs.close(fd)
|
|
if (cb) cb(fsErr, written)
|
|
})
|
|
}
|
|
|
|
// run non dependent async calls at the same time ish
|
|
canvas.toBuffer(function (canvasErr, _buf) {
|
|
if (canvasErr) return cb(canvasErr)
|
|
buf = _buf
|
|
if (fd) fdAndBuf()
|
|
})
|
|
|
|
fs.open(path, 'w', function (fsErr, _fd) {
|
|
if (fsErr) return cb(fsErr)
|
|
fd = _fd
|
|
if (buf) fdAndBuf()
|
|
})
|
|
})
|
|
}
|
|
|
|
function saveSvg (path, text, options, cb) {
|
|
exports.drawSvg(text, function (error, code) {
|
|
if (!error) {
|
|
fs.writeFile(path, code, function (fsErr) {
|
|
return cb(fsErr, fsErr ? null : code)
|
|
})
|
|
}
|
|
})
|
|
}
|
|
|
|
//
|
|
// this returns an array of points that have either a 0 or 1 value representing 0 for light and 1 for dark
|
|
// these values include points in the white edge of the qrcode because that edge is actually part of the spec
|
|
//
|
|
exports.drawBitArray = function (text, options, cb) {
|
|
if (typeof options === 'function') {
|
|
cb = options
|
|
options = {}
|
|
}
|
|
options = parseOptions(options)
|
|
|
|
var drawInstance = new QRCodeDraw()
|
|
drawInstance.drawBitArray(text, options, function (error, bits, width) {
|
|
cb(error, bits, width)
|
|
})
|
|
}
|
|
|
|
//
|
|
// draw qr in your terminal!
|
|
//
|
|
exports.drawText = function (text, options, cb) {
|
|
if (typeof options === 'function') {
|
|
cb = options
|
|
options = {}
|
|
}
|
|
|
|
var drawInstance = new QRCodeDraw()
|
|
drawInstance.drawBitArray(text, function (error, bits, width) {
|
|
if (!error) {
|
|
var code = terminalRender.renderBits(bits, width)
|
|
cb(error, code)
|
|
} else {
|
|
cb(error, null)
|
|
}
|
|
})
|
|
}
|
|
|
|
exports.drawSvg = function (text, options, cb) {
|
|
if (typeof options === 'function') {
|
|
cb = options
|
|
options = {}
|
|
}
|
|
|
|
var drawInstance = new QRCodeDraw()
|
|
drawInstance.drawBitArray(text, function (error, bits, width) {
|
|
if (!error) {
|
|
var code = svgRender.renderBits(bits, width, options)
|
|
cb(error, code)
|
|
} else {
|
|
cb(error, null)
|
|
}
|
|
})
|
|
}
|