Add some (fun?) extras for the terminally curious

This commit is contained in:
Robin Stuart 2020-08-23 20:32:33 +01:00
parent 9f5ae4cbb2
commit 3d606858bf
8 changed files with 831 additions and 0 deletions

26
extras/README Normal file
View file

@ -0,0 +1,26 @@
This folder contains some extra tools to provide functionality which
may be useful, or just interesting, but fall outside the remit of the
Zint program. These small programs have been written by Robin Stuart
and are released to the public domain.
Font Encoding Tools
-------------------
daft.c
ida_2d.c
stroke.c
zebu_pdf.c
These code snippets show how Zint can be used to create the text
necessary to display symbols using a range of fonts available online.
See the individual files for information about the specific fonts.
Some of these fonts are free whereas others require licensing, check the
specific websites before use.
Obsolete Symbologies
--------------------
cuecat.c
kartrak.c
sunburst.c
These are stand-alone tools for encoding data in some more obscure and
obsolete formats. More information is given within the file.

173
extras/cuecat.c Normal file
View file

@ -0,0 +1,173 @@
/*
* cuecat.c
*
* This code creates barcodes as intended for use with the CueCat scheme (without the
* "cue" symbol which may still be trademarked). As the system was ultimately not
* successful this is now simply a curiosity.
*
* "The CueCat, styled :CueCat with a leading colon, is a cat-shaped handheld barcode
* reader that was released in 2000 by the now-defunct Digital Convergence Corporation.
* The CueCat enabled a user to open a link to an Internet URL by scanning a barcode
* called a "cue" by Digital Convergence appearing in an article or catalog or on
* some other printed matter."
*
* For more information:
* https://linas.org/banned/cuecat/www.fluent-access.com.wtpapers.cuecat.index.html
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
static const char *C128Table[107] = {
/* Code 128 character encodation */
"212222", "222122", "222221", "121223", "121322", "131222", "122213",
"122312", "132212", "221213", "221312", "231212", "112232", "122132", "122231", "113222",
"123122", "123221", "223211", "221132", "221231", "213212", "223112", "312131", "311222",
"321122", "321221", "312212", "322112", "322211", "212123", "212321", "232121", "111323",
"131123", "131321", "112313", "132113", "132311", "211313", "231113", "231311", "112133",
"112331", "132131", "113123", "113321", "133121", "313121", "211331", "231131", "213113",
"213311", "213131", "311123", "311321", "331121", "312113", "312311", "332111", "314111",
"221411", "431111", "111224", "111422", "121124", "121421", "141122", "141221", "112214",
"112412", "122114", "122411", "142112", "142211", "241211", "221114", "413111", "241112",
"134111", "111242", "121142", "121241", "114212", "124112", "124211", "411212", "421112",
"421211", "212141", "214121", "412121", "111143", "111341", "131141", "114113", "114311",
"411113", "411311", "113141", "114131", "311141", "411131", "211412", "211214", "211232",
"2331112"
};
void print_head(char cat_number[]) {
printf("<?xml version=\"1.0\" standalone=\"no\"?>\n");
printf("<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\"\n");
printf(" \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n");
printf("<svg width=\"149.60\" height=\"36.00\" version=\"1.1\"\n");
printf(" xmlns=\"http://www.w3.org/2000/svg\">\n");
printf(" <desc>CueCat %s</desc>\n\n", cat_number);
printf(" <g id=\"cuecat\" fill = \"#000000\">\n");
printf(" <rect x=\"0\" y=\"0\" width=\"149.60\" height=\"36.00\" fill=\"#ffffff\" />\n");
}
void print_cue() {
/* Just dots and triangles as the :C symbol may still be a trademark */
printf(" <circle cx=\"7.00\" cy=\"12.50\" r=\"3.50\" fill=\"red\" />\n");
printf(" <circle cx=\"7.00\" cy=\"23.50\" r=\"3.50\" fill=\"red\" />\n");
printf(" <polygon points=\"14.00,4.00 14.00,32.00 25.60,32.00\" />\n");
printf(" <polygon points=\"134.00,4.00 145.60,4.00 145.60,32.00\" />\n");
}
void print_data(char pattern[]) {
/* Output the lines of the barcode at an attractive 22.5 degree angle */
double posn = 24;
int length = strlen(pattern);
int i;
for (i = 0; i < length; i++) {
if ((i % 2) == 0) {
printf(" <polygon points=\"%.2f,4.00 %.2f,4.00 %.2f,32.00 %.2f,32.00\" />\n",
posn, posn + (pattern[i] - '0'), posn + (pattern[i] - '0') + 11.6, posn + 11.6);
}
posn += (pattern[i] - '0');
}
}
void print_hrt(char cat_number[]) {
/* Put readable text at the bottom of the symbol */
char hrt[25];
int i, j;
printf(" <rect x=\"57.00\" y=\"28.00\" width=\"61.00\" height=\"5.00\" fill=\"white\" />\n");
strcpy(hrt, "C ");
for (i = 0, j = 2; i < strlen(cat_number); i++) {
hrt[j] = cat_number[i];
j++;
if ((i % 2) != 0) {
hrt[j] = ' ';
j++;
}
}
hrt[j] = '\0';
printf(" <text x=\"58.00\" y=\"32.00\" font-family=\"Verdana\" font-size=\"5\">%s</text>\n", hrt);
}
void print_foot() {
printf(" </g>\n");
printf("</svg>\n");
}
int main(int argc, char** argv) {
int in_length;
char cat_number[16];
char pattern[90];
int cw[7];
int i;
int total_sum;
if (argc != 2) {
/* Only command line input should be the number to encode */
printf("Usage: cuecat {number}\n");
printf("Where {number} is the number to be encoded, up to 14 digits\n");
return 0;
} else {
in_length = strlen(argv[1]);
if (in_length > 14) {
/* Check maximum length */
printf("Input data too long\n");
return 0;
} else {
/* Add padding if needed */
strcpy(cat_number, "");
for(i = in_length; i < 14; i++) {
strcat(cat_number, "0");
}
strcat(cat_number, argv[1]);
}
}
/* Check input is numeric */
for (i = 0; i < 10; i++) {
if (!(isdigit(cat_number[i]))) {
printf("Invalid character(s) in input data\n");
return 0;
}
}
// There is no 'Start' character
strcpy(pattern, "");
for (i = 0; i < 7; i ++) {
cw[i] = (cat_number[i * 2] - '0') * 10;
cw[i] += cat_number[(i * 2) + 1] - '0';
strcat(pattern, C128Table[cw[i]]);
if (cw[i] >= 96) {
/* CueCat can't decode number pairs above 95 */
printf("Invalid input data\n");
return 0;
}
}
/* check digit calculation */
total_sum = 0;
for (i = 0; i < 7; i++) {
if (i > 0) {
cw[i] *= i;
}
total_sum += cw[i];
}
strcat(pattern, C128Table[total_sum % 103]);
strcat(pattern, C128Table[106]); // Stop
/* Start ouputting SVG file */
print_head(cat_number);
print_cue();
print_data(pattern);
print_hrt(cat_number);
print_foot();
}

68
extras/daft.c Normal file
View file

@ -0,0 +1,68 @@
/*
* daft.c
*
* This code uses Zint to encode data into a USPS Intelligent
* Mail symbol, and then converts the output to "DAFT code"
* which is used by commercial fonts to display this and
* similar 4-state symbologies.
*
* This code can be compiled with:
*
* gcc -o daft daft.c -lzint
*
* The output characters are:
*
* D = Descender
* A = Ascender
* F = Full
* T = Tracker
*
*/
#include <stdio.h>
#include <zint.h>
#include <string.h>
int main(int argc, char **argv)
{
struct zint_symbol *my_symbol;
int error = 0;
int x, y, glyph;
my_symbol = ZBarcode_Create();
my_symbol->symbology = BARCODE_USPS_IMAIL; // Change symbology here
my_symbol->output_options = OUT_BUFFER_INTERMEDIATE;
error = ZBarcode_Encode(my_symbol, argv[1], strlen(argv[1]));
if (error != 0)
{
printf("%s\n", my_symbol->errtxt);
}
if (error >= ZINT_ERROR_TOO_LONG)
{
ZBarcode_Delete(my_symbol);
return 1;
}
for (x = 0; x < my_symbol->width; x+= 2) {
glyph = 0;
if ((my_symbol->encoded_data[2][x / 8] >> (x % 8)) & 1) {
glyph += 1;
}
if ((my_symbol->encoded_data[0][x / 8] >> (x % 8)) & 1) {
glyph += 2;
}
switch (glyph) {
case 0: printf("T"); break;
case 1: printf("D"); break;
case 2: printf("A"); break;
case 3: printf("F"); break;
}
glyph = 0;
}
printf("\n");
ZBarcode_Delete(my_symbol);
return 0;
}

64
extras/ida_2d.c Normal file
View file

@ -0,0 +1,64 @@
/*
* ida_2d.c
*
* This code uses Zint to encode data into a QR Code and then outputs
* the symbol as text suitable for use with the IDAutomation2D font
*
* This code can be adapted to use any matrix symbology by changing the
* line indicated.
*
* This code can be compiled with:
*
* gcc -o ida_2d ida_2d.c -lzint
*
* Fonts can be downloaded from https://www.idautomation.com/
*
*/
#include <stdio.h>
#include <zint.h>
#include <string.h>
int main(int argc, char **argv)
{
struct zint_symbol *my_symbol;
int error = 0;
int x, y, sub, glyph;
my_symbol = ZBarcode_Create();
my_symbol->symbology = BARCODE_QRCODE; // Change symbology here
my_symbol->output_options = OUT_BUFFER_INTERMEDIATE;
error = ZBarcode_Encode(my_symbol, argv[1], strlen(argv[1]));
if (error != 0)
{
printf("%s\n", my_symbol->errtxt);
}
if (error >= ZINT_ERROR_TOO_LONG)
{
ZBarcode_Delete(my_symbol);
return 1;
}
for (y = 0; y < my_symbol->rows; y += 4) {
for (x = 0; x < my_symbol->width; x++) {
glyph = 0;
for (sub = 0; sub < 4; sub++) {
glyph *= 2;
if ((y + sub) < my_symbol->rows) {
if (((my_symbol->encoded_data[y + sub][x / 8] >> (x % 8)) & 1) == 0) {
glyph += 1;
}
} else {
glyph += 1;
}
}
glyph += 'A';
printf("%c", glyph);
}
printf("\n");
}
ZBarcode_Delete(my_symbol);
return 0;
}

216
extras/kartrak.c Normal file
View file

@ -0,0 +1,216 @@
/*
* kartrak.c
*
* This code generates KarTrak codes as were previously used in the rail industry of the US
* (description below). Output is as an SVG file. This system is now obsolete but perhaps
* this will be of interest to model railway enthusiasts.
*
* "KarTrak, sometimes KarTrak ACI (for Automatic Car Identification) is a colored
* bar code system designed to automatically identify rail cars and other rolling stock.
* KarTrak was made a requirement in North America, but technical problems led to
* abandonment of the system in the late 1970s."
*
* https://en.wikipedia.org/wiki/KarTrak
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void print_head(char car_number[], double bordersize) {
printf("<?xml version=\"1.0\" standalone=\"no\"?>\n");
printf("<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\"\n");
printf(" \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n");
printf("<svg width=\"%.2fin\" height=\"%.2fin\" version=\"1.1\"\n", 5.75 + (2 * bordersize), 17.5 + (2 * bordersize));
printf(" xmlns=\"http://www.w3.org/2000/svg\">\n");
printf(" <desc>KarTrak ACI %s</desc>\n\n", car_number);
printf(" <g id=\"kartrak\" fill = \"#000000\">\n");
printf(" <rect x=\"0in\" y=\"0in\" width=\"%.2fin\" height=\"%.2fin\" fill=\"#000000\" />\n", 5.75 + (2 * bordersize), 17.5 + (2 * bordersize));
}
void print_foot() {
printf(" </g>\n");
printf("</svg>\n");
}
void print_check(double x, double y) {
/* Print checkerboard */
int w, h;
for (h = 0; h < 6; h++) {
for (w = 0; w < 69; w++) {
if (((w + h) % 2) == 0) {
printf(" <rect x=\"%.2fin\" y=\"%.2fin\" width=\"0.08in\" height=\"0.08in\" fill=\"#ffffff\" />\n", x + (0.083 * w), y + (0.083 * h));
}
}
}
}
void hrt(double x, double y, char c[]) {
/* Add text to the left */
printf(" <text x=\"%.2fin\" y=\"%.2fin\" font-family=\"Verdana\" font-size=\"25\">%s</text>\n", x + 0.2, y + 0.9, c);
}
void back_square(double x, double y) {
printf(" <rect x=\"%.2fin\" y=\"%.2fin\" width=\"0.17in\" height=\"0.25in\" fill=\"#ffffff\" />\n", x + 0.2, y + 0.7);
}
void print_zero(double x, double y) {
print_check(x, y);
printf(" <rect x=\"%.2fin\" y=\"%.2fin\" width=\"5.75in\" height=\"0.5in\" fill=\"#0000e0\" />\n", x, y + 0.5);
hrt(x, y, "0");
}
void print_one(double x, double y) {
print_check(x, y);
print_check(x, y + 0.5);
back_square(x, y);
hrt(x, y, "1");
}
void print_two(double x, double y) {
printf(" <rect x=\"%.2fin\" y=\"%.2fin\" width=\"5.75in\" height=\"0.5in\" fill=\"#ef0000\" />\n", x, y);
print_check(x, y + 0.5);
back_square(x, y);
hrt(x, y, "2");
}
void print_three(double x, double y) {
printf(" <rect x=\"%.2fin\" y=\"%.2fin\" width=\"5.75in\" height=\"0.5in\" fill=\"#ef0000\" />\n", x, y + 0.5);
hrt(x, y, "3");
}
void print_four(double x, double y) {
printf(" <rect x=\"%.2fin\" y=\"%.2fin\" width=\"5.75in\" height=\"1.00in\" fill=\"#ef0000\" />\n", x, y);
hrt(x, y, "4");
}
void print_five(double x, double y) {
printf(" <rect x=\"%.2fin\" y=\"%.2fin\" width=\"5.75in\" height=\"0.5in\" fill=\"#0000e0\" />\n", x, y + 0.5);
hrt(x, y, "5");
}
void print_six(double x, double y) {
printf(" <rect x=\"%.2fin\" y=\"%.2fin\" width=\"5.75in\" height=\"0.5in\" fill=\"#0000e0\" />\n", x, y);
print_check(x, y + 0.5);
back_square(x, y);
hrt(x, y, "6");
}
void print_seven(double x, double y) {
print_check(x, y);
printf(" <rect x=\"%.2fin\" y=\"%.2fin\" width=\"5.75in\" height=\"0.5in\" fill=\"#ef0000\" />\n", x, y + 0.5);
hrt(x, y, "7");
}
void print_eight(double x, double y) {
print_check(x, y + 0.5);
back_square(x, y);
hrt(x, y, "8");
}
void print_nine(double x, double y) {
printf(" <rect x=\"%.2fin\" y=\"%.2fin\" width=\"5.75in\" height=\"1.00in\" fill=\"#0000e0\" />\n", x, y);
hrt(x, y, "9");
}
void print_ten(double x, double y) {
printf(" <rect x=\"%.2fin\" y=\"%.2fin\" width=\"5.75in\" height=\"0.5in\" fill=\"#ef0000\" />\n", x, y);
printf(" <rect x=\"%.2fin\" y=\"%.2fin\" width=\"5.75in\" height=\"0.5in\" fill=\"#0000e0\" />\n", x, y + 0.5);
hrt(x, y, "10");
}
void print_start(double bordersize) {
printf(" <rect x=\"%.2fin\" y=\"%.2fin\" width=\"4.50in\" height=\"0.5in\" fill=\"#0000e0\" />\n", bordersize, 16.5 + bordersize);
printf(" <rect x=\"%.2fin\" y=\"%.2fin\" width=\"4.50in\" height=\"0.5in\" fill=\"#ef0000\" />\n", bordersize + 1.25, 17.0 + bordersize);
hrt(bordersize, 16.0 + bordersize, "START");
}
void print_stop(double bordersize) {
printf(" <rect x=\"%.2fin\" y=\"%.2fin\" width=\"4.50in\" height=\"0.5in\" fill=\"#0000e0\" />\n", bordersize + 1.25, 1.35 + bordersize);
printf(" <rect x=\"%.2fin\" y=\"%.2fin\" width=\"4.50in\" height=\"0.5in\" fill=\"#ef0000\" />\n", bordersize, 1.85 + bordersize);
hrt(bordersize, 1.35 + bordersize, "STOP");
}
void print_label(int posn, double bordersize, int digit) {
double y = ((17.5 + bordersize + 0.375) - ((posn + 1) * 1.375));
switch (digit) {
case 0: print_zero(bordersize, y); break;
case 1: print_one(bordersize, y); break;
case 2: print_two(bordersize, y); break;
case 3: print_three(bordersize, y); break;
case 4: print_four(bordersize, y); break;
case 5: print_five(bordersize, y); break;
case 6: print_six(bordersize, y); break;
case 7: print_seven(bordersize, y); break;
case 8: print_eight(bordersize, y); break;
case 9: print_nine(bordersize, y); break;
case 10: print_ten(bordersize, y); break;
}
}
int main(int argc, char** argv) {
int in_length;
char car_number[12];
int i;
int checksum = 0;
int checkdigit;
double bordersize = 3.0;
if (argc != 2) {
/* Only command line input should be the number to encode */
printf("Usage: kartrak {number}\n");
printf("Where {number} is the number to be encoded, up to 10 digits\n");
return 0;
} else {
in_length = strlen(argv[1]);
if (in_length > 10) {
/* Check maximum length */
printf("Input data too long\n");
return 0;
} else {
/* Add padding if needed */
strcpy(car_number, "");
for(i = in_length; i < 10; i++) {
strcat(car_number, "0");
}
strcat(car_number, argv[1]);
}
}
/* Check input is numeric */
for (i = 0; i < 10; i++) {
if ((car_number[i] < '0') || (car_number[i] > '9')) {
printf("Invalid character(s) in input data\n");
return 0;
}
checksum += (car_number[i] - '0') * (1 << i);
}
/* Calculate check digit */
checkdigit = checksum % 11;
print_head(car_number, bordersize);
/* Start character */
print_start(bordersize);
/* Data */
for (i = 0; i < 10; i++) {
print_label((i + 1), bordersize, car_number[i] - '0');
}
/* Stop character */
print_stop(bordersize);
/* Check digit */
print_label(12, bordersize, checkdigit);
print_foot();
return (EXIT_SUCCESS);
}

89
extras/stroke.c Normal file
View file

@ -0,0 +1,89 @@
/*
* stroke.c
*
* This code uses Zint to encode data in QR Code and then output in
* the correct format to use StrokeScribe 2D font. This can be adapted
* to encode any matrix symbology using this font.
*
* The same code can also be used to resolve PDF417 symbols with the
* StrokeScribe 417 font and linear symbols with the StrokeScribe 1D
* font, all of which are available from the same souce.
*
* This code can be compiled with:
*
* gcc -o stroke stroke.c -lzint
*
* The fonts are available from:
*
* https://strokescribe.com/en/free-version-barcode-truetype-fonts.html
*
*/
#include <stdio.h>
#include <zint.h>
#include <string.h>
int main(int argc, char **argv)
{
struct zint_symbol *my_symbol;
int error = 0;
int x, y, glyph, sub;
my_symbol = ZBarcode_Create();
my_symbol->symbology = BARCODE_QRCODE; // Change symbology here
my_symbol->output_options = OUT_BUFFER_INTERMEDIATE;
error = ZBarcode_Encode(my_symbol, argv[1], strlen(argv[1]));
if (error != 0)
{
printf("%s\n", my_symbol->errtxt);
}
if (error >= ZINT_ERROR_TOO_LONG)
{
ZBarcode_Delete(my_symbol);
return 1;
}
sub = 0;
glyph = 0;
for (y = 0; y < my_symbol->rows; y++) {
for (x = 0; x < my_symbol->width; x++) {
glyph *= 2;
if ((my_symbol->encoded_data[y][x / 8] >> (x % 8)) & 1) {
glyph += 1;
}
sub++;
if (sub == 5) {
if (glyph <= 25) {
printf("%c", glyph + 'A');
} else {
printf("%c", (glyph - 26) + 'a');
}
sub = 0;
glyph = 0;
}
}
if (sub == 4) {
printf("%c", glyph + 'g');
}
if (sub == 3) {
if (glyph <= 3) {
printf("%c", glyph + 'w');
} else {
printf("%c", (glyph - 4) + '0');
}
}
if (sub == 2) {
printf("%c", glyph + '4');
}
if (sub == 1) {
printf("%c", glyph + '8');
}
printf("\n");
sub = 0;
glyph = 0;
}
ZBarcode_Delete(my_symbol);
return 0;
}

120
extras/sunburst.c Normal file
View file

@ -0,0 +1,120 @@
/*
* sunburst.c
*
* Many encoding schemes were put forward when the UPC system was being considered,
* and this code encodes numeric data according to one of the more interesting looking
* varieties. The system proposed by Charecogn Systems Inc. doesn't seem to have had
* an official name, but "sunburst" seems appropriate from its appearance. The idea was
* that the symbol would be read by a sensor mounted on a rotating head.
*
* This code takes numeric data and produces an image as an SVG.
*
* More details in US Patent 3,636,317, Filed April 28th 1969.
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
void print_head(char upc_number[]) {
printf("<?xml version=\"1.0\" standalone=\"no\"?>\n");
printf("<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\"\n");
printf(" \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n");
printf("<svg width=\"100\" height=\"100\" version=\"1.1\"\n");
printf(" xmlns=\"http://www.w3.org/2000/svg\">\n");
printf(" <desc>Sunburst %s</desc>\n\n", upc_number);
printf(" <g id=\"sunburst\" fill = \"#000000\">\n");
printf(" <rect x=\"0\" y=\"0\" width=\"100\" height=\"100\" fill=\"#ffffff\" />\n");
}
void print_foot() {
printf(" </g>\n");
printf("</svg>\n");
}
static const char *torrey[11] = {
"01010101", "10010101", "01100101", "10100101", "01010110", "10010110",
"01100110", "10101010", "01011001", "10011001", "01001101"
// Two "surplus" codes were also defined as "01011010" and "10110010"
// In these codes 0 is dark and 1 is light
};
int main(int argc, char** argv) {
int in_length;
char upc_number[12];
char binary[100];
int i;
int posn;
int left, right;
double ax, ay, bx, by, cx, cy, dx, dy;
if (argc != 2) {
/* Only command line input should be the number to encode */
printf("Usage: sunburst {number}\n");
printf("Where {number} is the number to be encoded, up to 11 digits\n");
return 0;
} else {
in_length = strlen(argv[1]);
if (in_length > 11) {
/* Check maximum length */
printf("Input data too long\n");
return 0;
} else {
/* Add padding if needed */
strcpy(upc_number, "");
for(i = in_length; i < 11; i++) {
strcat(upc_number, "0");
}
strcat(upc_number, argv[1]);
}
}
/* Check input is numeric */
for (i = 0; i < 11; i++) {
if ((upc_number[i] < '0') || (upc_number[i] > '9')) {
printf("Invalid character(s) in input data\n");
return 0;
}
}
strcpy(binary, torrey[10]); // Start
for (i = 0; i < 11; i++) {
strcat(binary, torrey[upc_number[i] - '0']);
}
print_head(upc_number);
posn = 0;
do {
if (binary[posn] == '0') {
for (i = 0; binary[posn + i] == '0'; i++);
left = posn;
right = posn + i;
ax = 50.0 + (18.72 * cos(0.06545 * left - 1.5708));
ay = 50.0 + (18.72 * sin(0.06545 * left - 1.5708));
bx = 50.0 + (50.0 * cos(0.06545 * left - 1.5708));
by = 50.0 + (50.0 * sin(0.06545 * left - 1.5708));
cx = 50.0 + (50.0 * cos(0.06545 * right - 1.5708));
cy = 50.0 + (50.0 * sin(0.06545 * right - 1.5708));
dx = 50.0 + (18.72 * cos(0.06545 * right - 1.5708));
dy = 50.0 + (18.72 * sin(0.06545 * right - 1.5708));
printf(" <path d=\"M %.2f %.2f A 50.00 50.00 0 0 1 %.2f %.2f L %.2f %.2f A 18.72 18.72 0 0 0 %.2f %.2f Z\" />\n",
bx, by, cx, cy, dx, dy, ax, ay);
posn += i;
} else {
posn++;
}
} while (posn < 96);
print_foot();
return (EXIT_SUCCESS);
}

75
extras/zebu_pdf.c Normal file
View file

@ -0,0 +1,75 @@
/*
* zebu_pdf.c
*
* This code uses Zint to encode data into a PDF417 and then outputs
* the symbol as text suitable for use with Code PDF417 font by
* Grand Zebu.
*
* This code can be compiled with:
*
* gcc -o zebu_pdf zebu_pdf.c -lzint
*
* Grand Zebu's font can be downloaded from:
*
* https://grandzebu.net/informatique/codbar-en/pdf417.htm
*
*/
#include <stdio.h>
#include <zint.h>
#include <string.h>
int main(int argc, char **argv)
{
struct zint_symbol *my_symbol;
int error = 0;
int x, y, sub, glyph, group;
my_symbol = ZBarcode_Create();
my_symbol->symbology = BARCODE_PDF417;
my_symbol->output_options = OUT_BUFFER_INTERMEDIATE;
error = ZBarcode_Encode(my_symbol, argv[1], strlen(argv[1]));
if (error != 0)
{
printf("%s\n", my_symbol->errtxt);
}
if (error >= ZINT_ERROR_TOO_LONG)
{
ZBarcode_Delete(my_symbol);
return 1;
}
for (y = 0; y < my_symbol->rows; y++) {
printf("+*");
sub = 0;
glyph = 0;
group = 0;
for (x = 18; x < my_symbol->width - 19; x++) {
glyph *= 2;
if ((my_symbol->encoded_data[y][x / 8] >> (x % 8)) & 1) {
glyph++;
}
sub++;
if (sub == 5) {
if (glyph <= 5) {
printf("%c", glyph + 'A');
} else {
printf("%c", (glyph - 6) + 'a');
}
glyph = 0;
sub = 0;
group++;
}
if (group == 3) {
printf("*");
x += 2;
group = 0;
}
}
printf("-\n");
}
ZBarcode_Delete(my_symbol);
return 0;
}