Barcode Generator: Comments/Improvements on code?

edited August 2014 in Share Your Work

The following code implements a barcode generator (EAN-13).

I welcome comments or improvements of my code. Since I'm new to Processing I appreciate your feedback.

The code is also available as a GIST on github: Barcode generator

For a screenshot see: Tweet on Twitter.

/* 
 Barcode Generator (EAN-13) by @denkspuren, 2014-08-27, 14:22
 New BSD License: http://opensource.org/licenses/BSD-3-Clause

 http://en.wikipedia.org/wiki/International_Article_Number_(EAN)
 http://de.wikipedia.org/wiki/European_Article_Number

 Use: Press number keys to input a sequence of digits or use
      right/left arrow for navigation.
      Note: Rightmost digit is checksum digit. 
*/

int START_X = 30;
int START_Y = 20;
int LINE_LENGTH = 100;
int LINE_EXTRA  = 20;
int LINE_WEIGHT = 3;

int TEXT_PT = 20;
int pos = 0; // ranges from 0..11
Digit[] digits = new Digit[13];

int SIZE_X = 2*START_X + (3 + 6*7 + 5 + 6*7 + 3) * LINE_WEIGHT;
int SIZE_Y = 2*START_Y + LINE_LENGTH + LINE_EXTRA;

int ASCII_NULL = 48;
int ASCII_NINE = 57;

color WHITE = color(255,255,255);
color RED = color(255,0,0);
color BLUE = color(0,0,255);

String[] encoding = // encoding for digits 0..9 on right side
{ 
  "1110010", "1100110", "1101100", "1000010", "1011100", 
  "1001110", "1010000", "1000100", "1001000", "1110100"
};

String[] pattern = // 1st digit is encoded via pattern for digits on left side
{
  "OOOOOO", "OOEOEE", "OOEEOE", "OOEEEO", "OEOOEE", // 'O' means "odd" 
  "OEEOOE", "OEEEOO", "OEOEOE", "OEOEEO", "OEEOEO"  // 'E' means "even"
};

String reverseEncoding(String s) { // required for digits on left side (even)
  if ((s == null) || s.isEmpty()) return s;
  return reverseEncoding(s.substring(1)) + s.charAt(0);
}

String inverseEncoding(String s) { // required for digits on left side (odd)
  if ((s == null) || s.isEmpty()) return s;
  return ((s.charAt(0) == '1') ? '0' : '1') + inverseEncoding(s.substring(1));
}

int calc_checksumDigit(int[] digits) {
  int sum = 0;
  int multiplier = 3;
  for (int i=digits.length-1; i>=0; i--) {
    sum += digits[i] * multiplier;
    multiplier = (multiplier == 3) ? 1 : 3;
  }
  return (10 - sum % 10) % 10;
}

int draw_encoding(int x, int y, int length, String encoding) {
  for (int i=0; i<encoding.length (); i++) {
    if (encoding.charAt(i) == '1') line(x, y, x, y+length);
    x += LINE_WEIGHT;
  }
  return x;
}

void draw_barcode(int x, int y, int[] digits) {
  String code;
  String schema = pattern[digits[0]];
  x = draw_encoding(x, y, LINE_LENGTH+LINE_EXTRA, "101");
  for (int i=1; i<=6; i++) {
    code = (schema.charAt(i-1) == 'O') ?
           inverseEncoding(encoding[digits[i]]) :
           reverseEncoding(encoding[digits[i]]);
    x = draw_encoding(x, y, LINE_LENGTH, code);
  }
  x = draw_encoding(x, y, LINE_LENGTH+LINE_EXTRA, "01010");
  for (int i=7; i<=12; i++) {
    code = encoding[digits[i]];
    x = draw_encoding(x, y, LINE_LENGTH, code);
  }
  x = draw_encoding(x, y, LINE_LENGTH+LINE_EXTRA, "101");
}

class Digit {
  int x, y, value;

  Digit(int x, int y, int value) {
    this.x = x;
    this.y = y;
    this.value = value;
    draw(false);
  }

  void draw(boolean active) {
    fill(active ? RED : BLUE);
    text(value, x, y);
  }
}

void draw_digits(Digit[] digits) {
  for (Digit d: digits) d.draw(false);
}  

Digit[] initDigits() {
  int x = START_X - TEXT_PT/2;
  int y = START_Y + LINE_LENGTH + LINE_EXTRA;
  Digit[] digits = new Digit[13];
  digits[0] = new Digit(x, y, 0);
  x += 3 * LINE_WEIGHT + 2 * TEXT_PT/2;
  for (int i=1; i<=6; i++) {
    digits[i] = new Digit(x, y, 0);
    x += 7 * LINE_WEIGHT;
  }
  x += 4 * LINE_WEIGHT; // + TEXT_PT/2;
  for (int i=7; i<=12; i++) {
    digits[i] = new Digit(x, y, 0);
    x += 7 * LINE_WEIGHT;
  }
  return digits;
}

void set_ChecksumDigit(Digit[] digits) {
  int[] values = new int[12];
  for (int i=0; i<=11; i++) values[i] = digits[i].value;
  digits[12].value =  calc_checksumDigit(values);
}

int[] get_DigitValues(Digit[] digits) {
  int[] values = new int[13];
  for (int i=0; i<=12; i++) values[i] = digits[i].value;
  return values; 
}

void setup() {
  size(SIZE_X, SIZE_Y); // if used, must be first line of code in setup
  textSize(TEXT_PT);
  textAlign(CENTER);

  strokeWeight(LINE_WEIGHT);
  strokeCap(SQUARE);

  draw_barcode(START_X, START_Y, new int[] {0,0,0,0,0,0,0,0,0,0,0,0,0});
  digits = initDigits();
  digits[pos].draw(true);
}

void keyPressed() {
  if (key >= ASCII_NULL && key <= ASCII_NINE) {
    background(WHITE);
    digits[pos].value = key - ASCII_NULL;
    set_ChecksumDigit(digits);
    draw_barcode(START_X, START_Y, get_DigitValues(digits));
    draw_digits(digits);
    pos = (pos + 1) % 12;
    digits[pos].draw(true);
  }   
  else if (key == CODED) {
    if (keyCode == RIGHT) {
      digits[pos].draw(false);
      pos = (pos + 1) % 12;
      digits[pos].draw(true);
    }
    else if (keyCode == LEFT) {
      digits[pos].draw(false);
      pos = (pos + 11) % 12;
      digits[pos].draw(true);
    }
  } 
}

void draw() {  
}

Comments

Sign In or Register to comment.