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