3 * Copyright (C) 2001-2009 Jim Evins <evins@snaught.com>.
5 * This file is part of gLabels.
7 * gLabels is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
12 * gLabels is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with gLabels. If not, see <http://www.gnu.org/licenses/>.
23 #include "bc-backends.h"
26 #include <glib/gi18n.h>
28 #include "bc-postnet.h"
29 #include "bc-gnubarcode.h"
31 #include "bc-iec16022.h"
32 #include "bc-iec18004.h"
37 /*========================================================*/
38 /* Private macros and constants. */
39 /*========================================================*/
42 /*========================================================*/
44 /*========================================================*/
46 typedef glBarcode *(*glBarcodeNewFunc) (const gchar *id,
48 gboolean checksum_flag,
57 glBarcodeNewFunc new_barcode;
59 gboolean text_optional;
60 gboolean can_checksum;
61 gboolean checksum_optional;
62 gchar *default_digits;
63 gboolean can_freeform;
68 /*========================================================*/
69 /* Private globals. */
70 /*========================================================*/
72 static const Backend backends[] = {
74 { "POSTNET", N_("POSTNET (any)"), gl_barcode_postnet_new,
75 FALSE, FALSE, TRUE, FALSE, "12345-6789-12", FALSE, 11},
77 { "POSTNET-5", N_("POSTNET-5 (ZIP only)"), gl_barcode_postnet_new,
78 FALSE, FALSE, TRUE, FALSE, "12345", FALSE, 5},
80 { "POSTNET-9", N_("POSTNET-9 (ZIP+4)"), gl_barcode_postnet_new,
81 FALSE, FALSE, TRUE, FALSE, "12345-6789", FALSE, 9},
83 { "POSTNET-11", N_("POSTNET-11 (DPBC)"), gl_barcode_postnet_new,
84 FALSE, FALSE, TRUE, FALSE, "12345-6789-12", FALSE, 11},
86 { "CEPNET", N_("CEPNET"), gl_barcode_postnet_new,
87 FALSE, FALSE, TRUE, FALSE, "12345-678", FALSE, 8},
89 #ifdef HAVE_LIBBARCODE
91 { "EAN", N_("EAN (any)"), gl_barcode_gnubarcode_new,
92 TRUE, TRUE, TRUE, FALSE, "000000000000 00000", FALSE, 17},
94 { "EAN-8", N_("EAN-8"), gl_barcode_gnubarcode_new,
95 TRUE, TRUE, TRUE, FALSE, "0000000", FALSE, 7},
97 { "EAN-8+2", N_("EAN-8 +2"), gl_barcode_gnubarcode_new,
98 TRUE, TRUE, TRUE, FALSE, "0000000 00", FALSE, 9},
100 { "EAN-8+5", N_("EAN-8 +5"), gl_barcode_gnubarcode_new,
101 TRUE, TRUE, TRUE, FALSE, "0000000 00000", FALSE, 12},
103 { "EAN-13", N_("EAN-13"), gl_barcode_gnubarcode_new,
104 TRUE, TRUE, TRUE, FALSE, "000000000000", FALSE, 12},
106 { "EAN-13+2", N_("EAN-13 +2"), gl_barcode_gnubarcode_new,
107 TRUE, TRUE, TRUE, FALSE, "000000000000 00", FALSE, 14},
109 { "EAN-13+5", N_("EAN-13 +5"), gl_barcode_gnubarcode_new,
110 TRUE, TRUE, TRUE, FALSE, "000000000000 00000", FALSE, 17},
112 { "UPC", N_("UPC (UPC-A or UPC-E)"), gl_barcode_gnubarcode_new,
113 TRUE, TRUE, TRUE, FALSE, "00000000000 00000", FALSE, 16},
115 { "UPC-A", N_("UPC-A"), gl_barcode_gnubarcode_new,
116 TRUE, TRUE, TRUE, FALSE, "00000000000", FALSE, 11},
118 { "UPC-A+2", N_("UPC-A +2"), gl_barcode_gnubarcode_new,
119 TRUE, TRUE, TRUE, FALSE, "00000000000 00", FALSE, 13},
121 { "UPC-A+5", N_("UPC-A +5"), gl_barcode_gnubarcode_new,
122 TRUE, TRUE, TRUE, FALSE, "00000000000 00000", FALSE, 16},
124 { "UPC-E", N_("UPC-E"), gl_barcode_gnubarcode_new,
125 TRUE, TRUE, TRUE, FALSE, "000000", FALSE, 6},
127 { "UPC-E+2", N_("UPC-E +2"), gl_barcode_gnubarcode_new,
128 TRUE, TRUE, TRUE, FALSE, "000000 00", FALSE, 8},
130 { "UPC-E+5", N_("UPC-E +5"), gl_barcode_gnubarcode_new,
131 TRUE, TRUE, TRUE, FALSE, "000000 00000", FALSE, 11},
133 { "ISBN", N_("ISBN"), gl_barcode_gnubarcode_new,
134 TRUE, TRUE, TRUE, TRUE, "0-00000-000-0", FALSE, 10},
136 { "ISBN+5", N_("ISBN +5"), gl_barcode_gnubarcode_new,
137 TRUE, TRUE, TRUE, TRUE, "0-00000-000-0 00000", FALSE, 15},
139 { "Code39", N_("Code 39"), gl_barcode_gnubarcode_new,
140 TRUE, TRUE, TRUE, TRUE, "0000000000", TRUE, 10},
142 { "Code128", N_("Code 128"), gl_barcode_gnubarcode_new,
143 TRUE, TRUE, TRUE, TRUE, "0000000000", TRUE, 10},
145 { "Code128C", N_("Code 128C"), gl_barcode_gnubarcode_new,
146 TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
148 { "Code128B", N_("Code 128B"), gl_barcode_gnubarcode_new,
149 TRUE, TRUE, TRUE, TRUE, "0000000000", TRUE, 10},
151 { "I25", N_("Interleaved 2 of 5"), gl_barcode_gnubarcode_new,
152 TRUE, TRUE, TRUE, TRUE, "0000000000", TRUE, 10},
154 { "CBR", N_("Codabar"), gl_barcode_gnubarcode_new,
155 TRUE, TRUE, TRUE, TRUE, "0000000000", TRUE, 10},
157 { "MSI", N_("MSI"), gl_barcode_gnubarcode_new,
158 TRUE, TRUE, TRUE, TRUE, "0000000000", TRUE, 10},
160 { "PLS", N_("Plessey"), gl_barcode_gnubarcode_new,
161 TRUE, TRUE, TRUE, TRUE, "0000000000", TRUE, 10},
163 { "Code93", N_("Code 93"), gl_barcode_gnubarcode_new,
164 TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
166 #endif /* HAVE_LIBBARCODE */
170 { "AUSP", N_("Australia Post Standard"), gl_barcode_zint_new,
171 FALSE, FALSE, TRUE, FALSE, "12345678901234567890123", TRUE, 23},
173 { "AUSRP", N_("Australia Post Reply Paid"), gl_barcode_zint_new,
174 FALSE, FALSE, TRUE, FALSE, "12345678", TRUE, 8},
176 { "AUSRT", N_("Australia Post Route Code"), gl_barcode_zint_new,
177 FALSE, FALSE, TRUE, FALSE, "12345678", TRUE, 8},
179 { "AUSRD", N_("Australia Post Redirect"), gl_barcode_zint_new,
180 FALSE, FALSE, TRUE, FALSE, "12345678", TRUE, 8},
182 { "AZTEC", N_("Aztec Code"), gl_barcode_zint_new,
183 FALSE, FALSE, TRUE, FALSE, "1234567890", TRUE, 10},
185 { "AZRUN", N_("Aztec Rune"), gl_barcode_zint_new,
186 FALSE, FALSE, TRUE, FALSE, "255", TRUE, 3},
188 { "CBR", N_("Codabar"), gl_barcode_zint_new,
189 TRUE, TRUE, TRUE, FALSE, "ABCDABCDAB", TRUE, 10},
191 { "Code1", N_("Code One"), gl_barcode_zint_new,
192 FALSE, FALSE, TRUE, FALSE, "0000000000", TRUE, 10},
194 { "Code11", N_("Code 11"), gl_barcode_zint_new,
195 TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
197 { "C16K", N_("Code 16K"), gl_barcode_zint_new,
198 FALSE, FALSE, TRUE, FALSE, "0000000000", TRUE, 10},
200 { "C25M", N_("Code 2 of 5 Matrix"), gl_barcode_zint_new,
201 TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
203 { "C25I", N_("Code 2 of 5 IATA"), gl_barcode_zint_new,
204 TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
206 { "C25DL", N_("Code 2 of 5 Data Logic"), gl_barcode_zint_new,
207 TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
209 { "Code32", N_("Code 32 (Italian Pharmacode)"), gl_barcode_zint_new,
210 TRUE, TRUE, TRUE, FALSE, "12345678", TRUE, 8},
212 { "Code39", N_("Code 39"), gl_barcode_zint_new,
213 TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
215 { "Code39E", N_("Code 39 Extended"), gl_barcode_zint_new,
216 TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
218 { "Code49", N_("Code 49"), gl_barcode_zint_new,
219 FALSE, FALSE, TRUE, FALSE, "0000000000", TRUE, 10},
221 { "Code93", N_("Code 93"), gl_barcode_zint_new,
222 TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
224 { "Code128", N_("Code 128"), gl_barcode_zint_new,
225 TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
227 { "Code128B", N_("Code 128 (Mode C supression)"), gl_barcode_zint_new,
228 TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
230 { "DAFT", N_("DAFT Code"), gl_barcode_zint_new,
231 FALSE, FALSE, FALSE, FALSE, "DAFTDAFTDAFTDAFT", TRUE, 16},
233 { "DMTX", N_("Data Matrix"), gl_barcode_zint_new,
234 FALSE, FALSE, TRUE, FALSE, "0000000000", TRUE, 10},
236 { "DPL", N_("Deutsche Post Leitcode"), gl_barcode_zint_new,
237 TRUE, TRUE, TRUE, FALSE, "1234567890123", TRUE, 13},
239 { "DPI", N_("Deutsche Post Identcode"), gl_barcode_zint_new,
240 TRUE, TRUE, TRUE, FALSE, "12345678901", TRUE, 11},
242 { "KIX", N_("Dutch Post KIX Code"), gl_barcode_zint_new,
243 FALSE, FALSE, TRUE, FALSE, "0000000000", TRUE, 10},
245 { "EAN", N_("EAN"), gl_barcode_zint_new,
246 TRUE, TRUE, TRUE, FALSE, "1234567890123", FALSE, 13},
248 { "GMTX", N_("Grid Matrix"), gl_barcode_zint_new,
249 FALSE, FALSE, TRUE, FALSE, "0000000000", TRUE, 10},
251 { "GS1-128", N_("GS1-128"), gl_barcode_zint_new,
252 TRUE, TRUE, TRUE, FALSE, "[01]12345678901234", FALSE, 18},
254 { "RSS14", N_("GS1 DataBar-14"), gl_barcode_zint_new,
255 TRUE, TRUE, TRUE, FALSE, "1234567890123", TRUE, 13},
257 { "RSSLTD", "GS1 DataBar-14 Limited", gl_barcode_zint_new,
258 TRUE, TRUE, TRUE, FALSE, "1234567890123", TRUE, 13},
260 { "RSSEXP", "GS1 DataBar Extended", gl_barcode_zint_new,
261 TRUE, TRUE, TRUE, FALSE, "[01]12345678901234", FALSE, 18},
263 { "RSSS", N_("GS1 DataBar-14 Stacked"), gl_barcode_zint_new,
264 FALSE, FALSE, TRUE, FALSE, "0000000000", TRUE, 10},
266 { "RSSSO", N_("GS1 DataBar-14 Stacked Omni."), gl_barcode_zint_new,
267 FALSE, FALSE, TRUE, FALSE, "0000000000", TRUE, 10},
269 { "RSSSE", N_("GS1 DataBar Extended Stacked"), gl_barcode_zint_new,
270 FALSE, FALSE, TRUE, FALSE, "[01]12345678901234", FALSE, 18},
272 { "HIBC128", N_("HIBC Code 128"), gl_barcode_zint_new,
273 TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
275 { "HIBC39", N_("HIBC Code 39"), gl_barcode_zint_new,
276 TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
278 { "HIBCDM", N_("HIBC Data Matrix"), gl_barcode_zint_new,
279 FALSE, FALSE, TRUE, FALSE, "0000000000", TRUE, 10},
281 { "HIBCQR", N_("HIBC QR Code"), gl_barcode_zint_new,
282 FALSE, FALSE, TRUE, FALSE, "0000000000", TRUE, 10},
284 { "HIBCPDF", N_("HIBC PDF417"), gl_barcode_zint_new,
285 FALSE, FALSE, TRUE, FALSE, "0000000000", TRUE, 10},
287 { "HIBCMPDF", N_("HIBC Micro PDF417"), gl_barcode_zint_new,
288 FALSE, FALSE, TRUE, FALSE, "0000000000", TRUE, 10},
290 { "HIBCAZ", N_("HIBC Aztec Code"), gl_barcode_zint_new,
291 TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
293 { "I25", N_("Interleaved 2 of 5"), gl_barcode_zint_new,
294 TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
296 { "ISBN", N_("ISBN"), gl_barcode_zint_new,
297 TRUE, TRUE, TRUE, FALSE, "123456789", FALSE, 9},
299 { "ITF14", N_("ITF-14"), gl_barcode_zint_new,
300 TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
302 { "JAPAN", N_("Japanese Postal"), gl_barcode_zint_new,
303 FALSE, FALSE, TRUE, FALSE, "0000000000", TRUE, 10},
305 { "KOREA", N_("Korean Postal"), gl_barcode_zint_new,
306 TRUE, TRUE, TRUE, FALSE, "123456", FALSE, 6},
308 { "LOGM", N_("LOGMARS"), gl_barcode_zint_new,
309 TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
311 { "MAXI", N_("Maxicode"), gl_barcode_zint_new,
312 FALSE, FALSE, FALSE, FALSE, "0000000000", TRUE, 10},
314 { "MPDF", N_("Micro PDF417"), gl_barcode_zint_new,
315 FALSE, FALSE, TRUE, FALSE, "0000000000", TRUE, 10},
317 { "MQR", N_("Micro QR Code"), gl_barcode_zint_new,
318 FALSE, FALSE, TRUE, FALSE, "0000000000", TRUE, 10},
320 { "MSI", N_("MSI Plessey"), gl_barcode_zint_new,
321 TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
323 { "NVE", N_("NVE-18"), gl_barcode_zint_new,
324 TRUE, TRUE, TRUE, FALSE, "12345678901234567", FALSE, 17},
326 { "PDF", N_("PDF417"), gl_barcode_zint_new,
327 FALSE, FALSE, TRUE, FALSE, "0000000000", TRUE, 10},
329 { "PDFT", N_("PDF417 Truncated"), gl_barcode_zint_new,
330 FALSE, FALSE, TRUE, FALSE, "0000000000", TRUE, 10},
332 { "PLAN", N_("PLANET"), gl_barcode_zint_new,
333 FALSE, FALSE, TRUE, FALSE, "0000000000", TRUE, 10},
335 { "POSTNET", N_("PostNet"), gl_barcode_zint_new,
336 TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
338 { "PHARMA", N_("Pharmacode"), gl_barcode_zint_new,
339 FALSE, FALSE, TRUE, FALSE, "123456", FALSE, 6},
341 { "PHARMA2", N_("Pharmacode 2-track"), gl_barcode_zint_new,
342 FALSE, FALSE, TRUE, FALSE, "12345678", FALSE, 8},
344 { "PZN", N_("Pharmazentral Nummer (PZN)"), gl_barcode_zint_new,
345 TRUE, TRUE, TRUE, FALSE, "123456", FALSE, 6},
347 { "QR", N_("QR Code"), gl_barcode_zint_new,
348 TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
350 { "RM4", N_("Royal Mail 4-State"), gl_barcode_zint_new,
351 FALSE, FALSE, TRUE, FALSE, "0000000000", TRUE, 10},
353 { "TELE", N_("Telepen"), gl_barcode_zint_new,
354 TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
356 { "TELEX", N_("Telepen Numeric"), gl_barcode_zint_new,
357 TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
359 { "UPC-A", N_("UPC-A"), gl_barcode_zint_new,
360 TRUE, TRUE, TRUE, FALSE, "12345678901", FALSE, 11},
362 { "UPC-E", N_("UPC-E"), gl_barcode_zint_new,
363 TRUE, TRUE, TRUE, FALSE, "1234567", FALSE, 7},
365 { "USPS", N_("USPS One Code"), gl_barcode_zint_new,
366 FALSE, FALSE, TRUE, FALSE, "12345678901234567890", TRUE, 20},
368 { "PLS", N_("UK Plessey"), gl_barcode_zint_new,
369 TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
371 #endif /* HAVE_LIBZINT */
373 #ifdef HAVE_LIBIEC16022
375 { "IEC16022", N_("IEC16022 (DataMatrix)"), gl_barcode_iec16022_new,
376 FALSE, FALSE, TRUE, FALSE, "12345678", TRUE, 8},
378 #endif /* HAVE_LIBIEC16022 */
380 #ifdef HAVE_LIBQRENCODE
382 { "IEC18004", N_("IEC18004 (QRCode)"), gl_barcode_iec18004_new,
383 FALSE, FALSE, TRUE, FALSE, "12345678", TRUE, 8},
385 #endif /* HAVE_LIBQRENCODE */
387 { NULL, NULL, NULL, FALSE, FALSE, FALSE, FALSE, NULL, FALSE, 0}
392 /*========================================================*/
393 /* Private function prototypes. */
394 /*========================================================*/
396 static gint id_to_index (const gchar *id);
397 static gint name_to_index (const gchar *name);
399 /*---------------------------------------------------------------------------*/
400 /* Convert id to index into above table. */
401 /*---------------------------------------------------------------------------*/
403 id_to_index (const gchar *id)
408 return 0; /* NULL request default. I.e., the first element. */
411 for (i=0; backends[i].id != NULL; i++) {
412 if (g_ascii_strcasecmp (id, backends[i].id) == 0) {
417 g_message( "Unknown barcode id \"%s\"", id );
422 /*---------------------------------------------------------------------------*/
423 /* Convert name to index into above table. */
424 /*---------------------------------------------------------------------------*/
426 name_to_index (const gchar *name)
430 g_return_val_if_fail (name!=NULL, 0);
432 for (i=0; backends[i].id != NULL; i++) {
433 if (strcmp (name, gettext (backends[i].name)) == 0) {
438 g_message( "Unknown barcode name \"%s\"", name );
443 /*****************************************************************************/
444 /* Get a list of names for valid barcode styles. */
445 /*****************************************************************************/
447 gl_barcode_backends_get_styles_list (void)
452 for (i=0; backends[i].id != NULL; i++) {
453 list = g_list_prepend (list, g_strdup (gettext (backends[i].name)));
456 return g_list_reverse (list);
460 /*****************************************************************************/
461 /* Free up a previously allocated list of style names. */
462 /*****************************************************************************/
464 gl_barcode_backends_free_styles_list (GList *styles_list)
468 for (p=styles_list; p != NULL; p=p->next) {
473 g_list_free (styles_list);
477 /*****************************************************************************/
478 /* Return an appropriate set of digits for the given barcode style. */
479 /*****************************************************************************/
481 gl_barcode_backends_default_digits (const gchar *id,
486 i = id_to_index (id);
488 if (backends[i].can_freeform) {
490 return g_strnfill (MAX (n,1), '0');
494 return g_strdup (backends[i].default_digits);
500 /*****************************************************************************/
501 /* Query text capabilities. */
502 /*****************************************************************************/
504 gl_barcode_backends_can_text (const gchar *id)
506 return backends[id_to_index (id)].can_text;
511 gl_barcode_backends_text_optional (const gchar *id)
513 return backends[id_to_index (id)].text_optional;
517 /*****************************************************************************/
518 /* Query checksum capabilities. */
519 /*****************************************************************************/
521 gl_barcode_backends_can_csum (const gchar *id)
523 return backends[id_to_index (id)].can_checksum;
528 gl_barcode_backends_csum_optional (const gchar *id)
530 return backends[id_to_index (id)].checksum_optional;
534 /*****************************************************************************/
535 /* Query if freeform input is allowed. */
536 /*****************************************************************************/
538 gl_barcode_backends_can_freeform (const gchar *id)
540 return backends[id_to_index (id)].can_freeform;
544 /*****************************************************************************/
545 /* Query prefered number of digits of input. */
546 /*****************************************************************************/
548 gl_barcode_backends_get_prefered_n (const gchar *id)
550 return backends[id_to_index (id)].prefered_n;
554 /*****************************************************************************/
555 /* Convert style to text. */
556 /*****************************************************************************/
558 gl_barcode_backends_id_to_name (const gchar *id)
560 return gettext (backends[id_to_index (id)].name);
564 /*****************************************************************************/
565 /* Convert name to style. */
566 /*****************************************************************************/
568 gl_barcode_backends_name_to_id (const gchar *name)
570 g_return_val_if_fail (name!=NULL, backends[0].id);
572 return backends[name_to_index (name)].id;
576 /*****************************************************************************/
577 /* Call appropriate barcode backend to create barcode in intermediate format.*/
578 /*****************************************************************************/
580 gl_barcode_backends_new_barcode (const gchar *id,
582 gboolean checksum_flag,
590 g_return_val_if_fail (digits!=NULL, NULL);
592 i = id_to_index (id);
593 gbc = backends[i].new_barcode (backends[i].id,
606 * Local Variables: -- emacs
608 * c-basic-offset: 8 -- emacs
609 * tab-width: 8 -- emacs
610 * indent-tabs-mode: nil -- emacs