node-qrcode-lite/lib/index.js
Vincenzo Greco 77064f5e5e Refactor/core ()
* 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
2016-12-16 23:45:08 +01:00

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)
}
})
}