codabar.js 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. /*
  2. * barcode generator - codabar
  3. */
  4. var gm = require('gm');
  5. var bmap = {
  6. '0': [0,0,0,0,0,1,1],
  7. '1': [0,0,0,0,1,1,0],
  8. '4': [0,0,1,0,0,1,0],
  9. '5': [1,0,0,0,0,1,0],
  10. '2': [0,0,0,1,0,0,1],
  11. '-': [0,0,0,1,1,0,0],
  12. '$': [0,0,1,1,0,0,0],
  13. '9': [1,0,0,1,0,0,0],
  14. '6': [0,1,0,0,0,0,1],
  15. '7': [0,1,0,0,1,0,0],
  16. '8': [0,1,1,0,0,0,0],
  17. '3': [1,1,0,0,0,0,0],
  18. 'C': [0,0,0,1,0,1,1],
  19. '*': [0,0,0,1,0,1,1],
  20. 'A': [0,0,1,1,0,1,0],
  21. 'T': [0,0,1,1,0,1,0],
  22. 'D': [0,0,0,1,1,1,0],
  23. 'E': [0,0,0,1,1,1,0],
  24. 'B': [0,1,0,1,0,0,1],
  25. 'N': [0,1,0,1,0,0,1],
  26. '.': [1,0,1,0,1,0,0],
  27. '/': [1,0,1,0,0,0,1],
  28. ':': [1,0,0,0,1,0,1],
  29. '+': [0,0,1,0,1,0,1],
  30. };
  31. const NARROW_RATIO = 10;
  32. const WIDE_RATIO = 25;
  33. module.exports.createCode = function (options, callback) {
  34. options.start = options.start || 'A';
  35. options.stop = options.stop || 'B';
  36. if (!options.w || !options.h) {
  37. return callback(new Error('Width and Height must be non-zero'), {});
  38. }
  39. options.data = (options.start + options.data + options.stop)
  40. .toUpperCase().replace(/[^0-9A-ENT*:+\/\.\$\-]/g, '').trim();
  41. if (!options.data) {
  42. return callback(new Error('No data given'), {});
  43. }
  44. var wideBars = 0,
  45. narrowBars = 0,
  46. wideBarTmp;
  47. for (var i in options.data) {
  48. wideBarTmp = bmap[options.data[i]].join().match(/1/g).length % 2 ? 3 : 2;
  49. wideBars += wideBarTmp;
  50. narrowBars += 7 - wideBarTmp;
  51. if (i) narrowBars++;
  52. }
  53. var wQuotient = options.w / (narrowBars * NARROW_RATIO + wideBars * WIDE_RATIO);
  54. var nBarWidth = NARROW_RATIO * wQuotient >> 0;
  55. var wBarWidth = WIDE_RATIO * wQuotient >> 0;
  56. if (nBarWidth < 1 || wBarWidth == nBarWidth) {
  57. return callback(new Error('Current settings will result in a ' +
  58. 'degenerate barcode'), {});
  59. }
  60. var img = gm(options.w, options.h, options.bgcolor),
  61. count = 0,
  62. pos = 0,
  63. ch,
  64. w;
  65. img.stroke(options.barcolor, 1);
  66. for (var i in options.data) {
  67. if (count++) {
  68. pos += nBarWidth;
  69. }
  70. ch = bmap[options.data[i]] || bmap['-'];
  71. for (var k in ch) {
  72. w = ch[k] ? wBarWidth : nBarWidth;
  73. if ( !(k % 2) ) {
  74. for (var j = 0; j < w; j++) {
  75. img.drawLine(pos + j, 0, pos + j, options.h);
  76. }
  77. }
  78. pos += w;
  79. }
  80. }
  81. img.stream(options.type, function (err, stdout, stderr) {
  82. callback(err, stdout);
  83. });
  84. }