comparison mupdf-source/thirdparty/zint/extras/kartrak.c @ 2:b50eed0cc0ef upstream

ADD: MuPDF v1.26.7: the MuPDF source as downloaded by a default build of PyMuPDF 1.26.4. The directory name has changed: no version number in the expanded directory now.
author Franz Glasner <fzglas.hg@dom66.de>
date Mon, 15 Sep 2025 11:43:07 +0200
parents
children
comparison
equal deleted inserted replaced
1:1d09e1dec1d9 2:b50eed0cc0ef
1 /*
2 * kartrak.c
3 *
4 * This code generates KarTrak codes as were previously used in the rail industry of the US
5 * (description below). Output is as an SVG file. This system is now obsolete but perhaps
6 * this will be of interest to model railway enthusiasts.
7 *
8 * "KarTrak, sometimes KarTrak ACI (for Automatic Car Identification) is a colored
9 * bar code system designed to automatically identify rail cars and other rolling stock.
10 * KarTrak was made a requirement in North America, but technical problems led to
11 * abandonment of the system in the late 1970s."
12 *
13 * https://en.wikipedia.org/wiki/KarTrak
14 *
15 */
16
17 #include <stdio.h>
18 #include <stdlib.h>
19 #include <string.h>
20
21 void print_head(char car_number[], double bordersize) {
22 printf("<?xml version=\"1.0\" standalone=\"no\"?>\n");
23 printf("<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\"\n");
24 printf(" \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n");
25 printf("<svg width=\"%.2fin\" height=\"%.2fin\" version=\"1.1\"\n", 5.75 + (2 * bordersize), 17.5 + (2 * bordersize));
26 printf(" xmlns=\"http://www.w3.org/2000/svg\">\n");
27 printf(" <desc>KarTrak ACI %s</desc>\n\n", car_number);
28 printf(" <g id=\"kartrak\" fill = \"#000000\">\n");
29 printf(" <rect x=\"0in\" y=\"0in\" width=\"%.2fin\" height=\"%.2fin\" fill=\"#000000\" />\n", 5.75 + (2 * bordersize), 17.5 + (2 * bordersize));
30 }
31
32 void print_foot() {
33 printf(" </g>\n");
34 printf("</svg>\n");
35 }
36
37 void print_check(double x, double y) {
38 /* Print checkerboard */
39 int w, h;
40
41 for (h = 0; h < 6; h++) {
42 for (w = 0; w < 69; w++) {
43 if (((w + h) % 2) == 0) {
44 printf(" <rect x=\"%.2fin\" y=\"%.2fin\" width=\"0.08in\" height=\"0.08in\" fill=\"#ffffff\" />\n", x + (0.083 * w), y + (0.083 * h));
45 }
46 }
47 }
48 }
49
50 void hrt(double x, double y, char c[]) {
51 /* Add text to the left */
52 printf(" <text x=\"%.2fin\" y=\"%.2fin\" font-family=\"Verdana\" font-size=\"25\">%s</text>\n", x + 0.2, y + 0.9, c);
53 }
54
55 void back_square(double x, double y) {
56 printf(" <rect x=\"%.2fin\" y=\"%.2fin\" width=\"0.17in\" height=\"0.25in\" fill=\"#ffffff\" />\n", x + 0.2, y + 0.7);
57 }
58
59 void print_zero(double x, double y) {
60 print_check(x, y);
61 printf(" <rect x=\"%.2fin\" y=\"%.2fin\" width=\"5.75in\" height=\"0.5in\" fill=\"#0000e0\" />\n", x, y + 0.5);
62 hrt(x, y, "0");
63 }
64
65 void print_one(double x, double y) {
66 print_check(x, y);
67 print_check(x, y + 0.5);
68 back_square(x, y);
69 hrt(x, y, "1");
70 }
71
72 void print_two(double x, double y) {
73 printf(" <rect x=\"%.2fin\" y=\"%.2fin\" width=\"5.75in\" height=\"0.5in\" fill=\"#ef0000\" />\n", x, y);
74 print_check(x, y + 0.5);
75 back_square(x, y);
76 hrt(x, y, "2");
77 }
78
79 void print_three(double x, double y) {
80 printf(" <rect x=\"%.2fin\" y=\"%.2fin\" width=\"5.75in\" height=\"0.5in\" fill=\"#ef0000\" />\n", x, y + 0.5);
81 hrt(x, y, "3");
82 }
83
84 void print_four(double x, double y) {
85 printf(" <rect x=\"%.2fin\" y=\"%.2fin\" width=\"5.75in\" height=\"1.00in\" fill=\"#ef0000\" />\n", x, y);
86 hrt(x, y, "4");
87 }
88
89 void print_five(double x, double y) {
90 printf(" <rect x=\"%.2fin\" y=\"%.2fin\" width=\"5.75in\" height=\"0.5in\" fill=\"#0000e0\" />\n", x, y + 0.5);
91 hrt(x, y, "5");
92 }
93
94 void print_six(double x, double y) {
95 printf(" <rect x=\"%.2fin\" y=\"%.2fin\" width=\"5.75in\" height=\"0.5in\" fill=\"#0000e0\" />\n", x, y);
96 print_check(x, y + 0.5);
97 back_square(x, y);
98 hrt(x, y, "6");
99 }
100
101 void print_seven(double x, double y) {
102 print_check(x, y);
103 printf(" <rect x=\"%.2fin\" y=\"%.2fin\" width=\"5.75in\" height=\"0.5in\" fill=\"#ef0000\" />\n", x, y + 0.5);
104 hrt(x, y, "7");
105 }
106
107 void print_eight(double x, double y) {
108 print_check(x, y + 0.5);
109 back_square(x, y);
110 hrt(x, y, "8");
111 }
112
113 void print_nine(double x, double y) {
114 printf(" <rect x=\"%.2fin\" y=\"%.2fin\" width=\"5.75in\" height=\"1.00in\" fill=\"#0000e0\" />\n", x, y);
115 hrt(x, y, "9");
116 }
117
118 void print_ten(double x, double y) {
119 printf(" <rect x=\"%.2fin\" y=\"%.2fin\" width=\"5.75in\" height=\"0.5in\" fill=\"#ef0000\" />\n", x, y);
120 printf(" <rect x=\"%.2fin\" y=\"%.2fin\" width=\"5.75in\" height=\"0.5in\" fill=\"#0000e0\" />\n", x, y + 0.5);
121 hrt(x, y, "10");
122 }
123
124 void print_start(double bordersize) {
125 printf(" <rect x=\"%.2fin\" y=\"%.2fin\" width=\"4.50in\" height=\"0.5in\" fill=\"#0000e0\" />\n", bordersize, 16.5 + bordersize);
126 printf(" <rect x=\"%.2fin\" y=\"%.2fin\" width=\"4.50in\" height=\"0.5in\" fill=\"#ef0000\" />\n", bordersize + 1.25, 17.0 + bordersize);
127 hrt(bordersize, 16.0 + bordersize, "START");
128 }
129
130 void print_stop(double bordersize) {
131 printf(" <rect x=\"%.2fin\" y=\"%.2fin\" width=\"4.50in\" height=\"0.5in\" fill=\"#0000e0\" />\n", bordersize + 1.25, 1.35 + bordersize);
132 printf(" <rect x=\"%.2fin\" y=\"%.2fin\" width=\"4.50in\" height=\"0.5in\" fill=\"#ef0000\" />\n", bordersize, 1.85 + bordersize);
133 hrt(bordersize, 1.35 + bordersize, "STOP");
134 }
135
136 void print_label(int posn, double bordersize, int digit) {
137 double y = ((17.5 + bordersize + 0.375) - ((posn + 1) * 1.375));
138
139 switch (digit) {
140 case 0: print_zero(bordersize, y); break;
141 case 1: print_one(bordersize, y); break;
142 case 2: print_two(bordersize, y); break;
143 case 3: print_three(bordersize, y); break;
144 case 4: print_four(bordersize, y); break;
145 case 5: print_five(bordersize, y); break;
146 case 6: print_six(bordersize, y); break;
147 case 7: print_seven(bordersize, y); break;
148 case 8: print_eight(bordersize, y); break;
149 case 9: print_nine(bordersize, y); break;
150 case 10: print_ten(bordersize, y); break;
151 }
152 }
153
154 int main(int argc, char** argv) {
155
156 int in_length;
157 char car_number[12];
158 int i;
159 int checksum = 0;
160 int checkdigit;
161 double bordersize = 3.0;
162
163 if (argc != 2) {
164 /* Only command line input should be the number to encode */
165 printf("Usage: kartrak {number}\n");
166 printf("Where {number} is the number to be encoded, up to 10 digits\n");
167 return 0;
168 } else {
169 in_length = strlen(argv[1]);
170 if (in_length > 10) {
171 /* Check maximum length */
172 printf("Input data too long\n");
173 return 0;
174 } else {
175 /* Add padding if needed */
176 strcpy(car_number, "");
177 for(i = in_length; i < 10; i++) {
178 strcat(car_number, "0");
179 }
180 strcat(car_number, argv[1]);
181 }
182 }
183
184 /* Check input is numeric */
185 for (i = 0; i < 10; i++) {
186 if ((car_number[i] < '0') || (car_number[i] > '9')) {
187 printf("Invalid character(s) in input data\n");
188 return 0;
189 }
190
191 checksum += (car_number[i] - '0') * (1 << i);
192 }
193
194 /* Calculate check digit */
195 checkdigit = checksum % 11;
196
197 print_head(car_number, bordersize);
198
199 /* Start character */
200 print_start(bordersize);
201
202 /* Data */
203 for (i = 0; i < 10; i++) {
204 print_label((i + 1), bordersize, car_number[i] - '0');
205 }
206
207 /* Stop character */
208 print_stop(bordersize);
209
210 /* Check digit */
211 print_label(12, bordersize, checkdigit);
212
213 print_foot();
214
215 return (EXIT_SUCCESS);
216 }