Blame onefile/gen-barcode.c

a5e8d6
a5e8d6
#include <stdio.h></stdio.h>
a5e8d6
#include <string.h></string.h>
a5e8d6
#include <stdlib.h></stdlib.h>
a5e8d6
#include <helianthus.h></helianthus.h>
a5e8d6
a5e8d6
#include "svg-save.inc.h"
a5e8d6
a5e8d6
a5e8d6
a5e8d6
char codes[10][2][10] = {
a5e8d6
  { "0001101", "0100111" }, // 0
a5e8d6
  { "0011001", "0110011" }, // 1
a5e8d6
  { "0010011", "0011011" }, // 2
a5e8d6
  { "0111101", "0100001" }, // 3
a5e8d6
  { "0100011", "0011101" }, // 4
a5e8d6
  { "0110001", "0111001" }, // 5
a5e8d6
  { "0101111", "0000101" }, // 6
a5e8d6
  { "0111011", "0010001" }, // 7
a5e8d6
  { "0110111", "0001001" }, // 8
a5e8d6
  { "0001011", "0010111" }, // 9
a5e8d6
};
a5e8d6
a5e8d6
a5e8d6
int seed;
a5e8d6
double pb = 10;
a5e8d6
double pw = 298;
a5e8d6
double ph = 210;
a5e8d6
double bh = 15;
a5e8d6
double th = 5;
a5e8d6
double step = 0.5;
a5e8d6
a5e8d6
a5e8d6
unsigned long long genNum()
a5e8d6
  { return rand()%1000000ull*1000000 + rand()%1000000; }
a5e8d6
a5e8d6
a5e8d6
void drawCode(FILE *f, unsigned long long num, double x, double y, double w, double h, double hh) {
a5e8d6
  char numA[10] = {};
a5e8d6
  char numB[10] = {};
a5e8d6
  char code[] =
a5e8d6
    "101"       // prefix
a5e8d6
    "[digit][digit][digit][digit][digit][digit]"
a5e8d6
    "01010"     // separator
a5e8d6
    "[digit][digit][digit][digit][digit][digit]"
a5e8d6
    "101";      // suffix
a5e8d6
  int count = sizeof(code) - 1;
a5e8d6
  char path[2048] = {};
a5e8d6
a5e8d6
  sprintf(numA, "%06d", (int)(num/1000000ull%1000000));
a5e8d6
  sprintf(numB, "%06d", (int)(num%1000000));
a5e8d6
a5e8d6
  for(int i = 0; i < 6; ++i) {
a5e8d6
    memcpy(code + 3 + i*7          , codes[numA[i]-'0'][0], 6);
a5e8d6
    memcpy(code + 3 + 6*7 + 5 + i*7, codes[numB[i]-'0'][1], 6);
a5e8d6
  }
a5e8d6
a5e8d6
  saveState();
a5e8d6
  noFill();
a5e8d6
  strokeWidth(w);
a5e8d6
  char *p = path;
a5e8d6
  for(int i = 0; i < count; ++i) {
a5e8d6
    if (code[i] != '1') continue;
a5e8d6
    int xl = i < 3
a5e8d6
          || (i >= 3 + 6*7 && i < 3 + 6*7 + 5)
a5e8d6
          || i >= 3 + 6*7 + 5 + 6*7;
a5e8d6
    double hhh = xl ? h + hh : h;
a5e8d6
    if (f) {
a5e8d6
      p += sprintf(p, "M %g %g l 0 %g ", x+i*w, y, hhh);
a5e8d6
    } else {
a5e8d6
      line(x+i*w, y, x+i*w, y + hhh);
a5e8d6
    }
a5e8d6
  }
a5e8d6
a5e8d6
  if (f) {
a5e8d6
    svgAddPath(f, path, w, FALSE);
a5e8d6
    svgAddText(f, x + (3+2)*w, y + h + hh, hh, numA);
a5e8d6
    svgAddText(f, x + (3+6*7+5+2)*w, y + h + hh, hh, numB);
a5e8d6
  } else {
a5e8d6
    textSize(hh);
a5e8d6
    textAlign(HALIGN_CENTER, VALIGN_TOP);
a5e8d6
    text(x + (3+3*7)*w, y + h, numA);
a5e8d6
    text(x + (3+6*7+5+3*7)*w, y + h, numB);
a5e8d6
  }
a5e8d6
  restoreState();
a5e8d6
}
a5e8d6
a5e8d6
a5e8d6
void drawAllCodes(FILE *f) {
a5e8d6
  srand(seed);
a5e8d6
a5e8d6
  double cw = step*(3 + 6*7 + 5 + 6*7 + 3);
a5e8d6
  double minSpace = 9*step;
a5e8d6
  double w = pw - 2*pb;
a5e8d6
  double h = ph - 2*pb;
a5e8d6
  int cols = (int)(w/(cw + minSpace) + 0.001);
a5e8d6
  int rows = (int)(h/(bh + th + th) + 0.001);
a5e8d6
  if (cols <= 0 || rows <= 0) return;
a5e8d6
a5e8d6
  double exw = w - cols*cw;
a5e8d6
  double exh = h - rows*(bh+th);
a5e8d6
  if (cols > 1) exw /= cols - 1;
a5e8d6
  if (rows > 1) exh /= rows - 1;
a5e8d6
a5e8d6
  double cww = cw + exw;
a5e8d6
  double chh = bh + th + exh;
a5e8d6
a5e8d6
  for(int r = 0; r < rows; ++r)
a5e8d6
    for(int c = 0; c < cols; ++c)
a5e8d6
      drawCode(f, genNum(), pb + c*cww, pb + r*chh, step, bh, th);
a5e8d6
}
a5e8d6
a5e8d6
a5e8d6
void generate() {
a5e8d6
  seed = rand();
a5e8d6
  FILE *f = svgBegin("data/output/generated-barcode.svg", pw, ph, 1);
a5e8d6
  drawAllCodes(f);
a5e8d6
  svgEnd(f);
a5e8d6
}
a5e8d6
a5e8d6
a5e8d6
a5e8d6
void init() {
a5e8d6
  generate();
a5e8d6
}
a5e8d6
a5e8d6
a5e8d6
void draw() {
a5e8d6
  double w = windowGetWidth();
a5e8d6
  double h = windowGetHeight();
a5e8d6
a5e8d6
  double kw = w/pw;
a5e8d6
  double kh = h/ph;
a5e8d6
  double k = kw < kh ? kw : kh;
a5e8d6
a5e8d6
  if (keyWentDown("space"))
a5e8d6
    generate();
a5e8d6
a5e8d6
  saveState();
a5e8d6
  translate(w/2, h/2);
a5e8d6
  zoom(k);
a5e8d6
  translate(-pw/2, -ph/2);
a5e8d6
  noFill();
a5e8d6
  strokeWidth(1);
a5e8d6
  rect(0, 0, pw, ph);
a5e8d6
  drawAllCodes(NULL);
a5e8d6
  restoreState();
a5e8d6
}
a5e8d6
a5e8d6
a5e8d6
int main() {
a5e8d6
  windowSetVariableFrameRate();
a5e8d6
  windowSetResizable(TRUE);
a5e8d6
  windowSetInit(&init);
a5e8d6
  windowSetDraw(&draw);
a5e8d6
  windowRun();
a5e8d6
}
a5e8d6