]> git.sur5r.net Git - glabels/blob - src/bc-backends.c
Imported Upstream version 3.4.0
[glabels] / src / bc-backends.c
1 /*
2  *  bc-backends.c
3  *  Copyright (C) 2001-2009  Jim Evins <evins@snaught.com>.
4  *
5  *  This file is part of gLabels.
6  *
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.
11  *
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.
16  *
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/>.
19  */
20
21 #include <config.h>
22
23 #include "bc-backends.h"
24
25 #include <glib.h>
26 #include <glib/gi18n.h>
27
28 #include "bc-builtin.h"
29 #include "bc-gnubarcode.h"
30 #include "bc-zint.h"
31 #include "bc-iec16022.h"
32 #include "bc-iec18004.h"
33
34 #include "debug.h"
35
36
37 /*========================================================*/
38 /* Private macros and constants.                          */
39 /*========================================================*/
40
41
42 /*========================================================*/
43 /* Private types.                                         */
44 /*========================================================*/
45
46 typedef lglBarcode *(*glBarcodeNewFunc) (const gchar    *id,
47                                          gboolean        text_flag,
48                                          gboolean        checksum_flag,
49                                          gdouble         w,
50                                          gdouble         h,
51                                          const gchar    *digits);
52
53
54 typedef struct {
55         gchar            *id;
56         gchar            *name;
57 } Backend;
58
59
60 typedef struct {
61         gchar            *backend_id;
62         gchar            *id;
63         gchar            *name;
64         glBarcodeNewFunc  new_barcode;
65         gboolean          can_text;
66         gboolean          text_optional;
67         gboolean          can_checksum;
68         gboolean          checksum_optional;
69         gchar            *default_digits;
70         gboolean          can_freeform;
71         guint             prefered_n;
72 } Style;
73
74
75 /*========================================================*/
76 /* Private globals.                                       */
77 /*========================================================*/
78
79 static const Backend backends[] = {
80
81         { "built-in",    N_("Built-in") },
82 #ifdef HAVE_LIBBARCODE
83         { "gnu-barcode", "GNU Barcode" },
84 #endif
85 #ifdef HAVE_LIBZINT
86         { "zint",        "Zint" },
87 #endif
88 #ifdef HAVE_LIBIEC16022
89         { "libiec16022", "IEC16022" },
90 #endif
91 #ifdef HAVE_LIBQRENCODE
92         { "libqrencode", "QREncode" },
93 #endif
94
95         { NULL, NULL }
96 };
97
98
99 static const Style styles[] = {
100
101         { "built-in", "POSTNET", N_("POSTNET (any)"), gl_barcode_builtin_new,
102           FALSE, FALSE, TRUE, FALSE, "12345-6789-12", FALSE, 11},
103
104         { "built-in", "POSTNET-5", N_("POSTNET-5 (ZIP only)"), gl_barcode_builtin_new,
105           FALSE, FALSE, TRUE, FALSE, "12345", FALSE, 5},
106
107         { "built-in", "POSTNET-9", N_("POSTNET-9 (ZIP+4)"), gl_barcode_builtin_new,
108           FALSE, FALSE, TRUE, FALSE, "12345-6789", FALSE, 9},
109
110         { "built-in", "POSTNET-11", N_("POSTNET-11 (DPBC)"), gl_barcode_builtin_new,
111           FALSE, FALSE, TRUE, FALSE, "12345-6789-12", FALSE, 11},
112
113         { "built-in", "CEPNET", N_("CEPNET"), gl_barcode_builtin_new,
114           FALSE, FALSE, TRUE, FALSE, "12345-678", FALSE, 8},
115
116         { "built-in", "ONECODE", N_("One Code"), gl_barcode_builtin_new,
117           FALSE, FALSE, TRUE, FALSE, "12345678901234567890", FALSE, 20},
118
119         { "built-in", "Code39", N_("Code 39"), gl_barcode_builtin_new,
120           TRUE, TRUE, TRUE, TRUE, "1234567890", TRUE, 10},
121
122         { "built-in", "Code39Ext", N_("Code 39 Extended"), gl_barcode_builtin_new,
123           TRUE, TRUE, TRUE, TRUE, "1234567890", TRUE, 10},
124
125 #ifdef HAVE_LIBBARCODE
126
127         { "gnu-barcode", "EAN", N_("EAN (any)"), gl_barcode_gnubarcode_new,
128           TRUE, TRUE, TRUE, FALSE, "000000000000 00000", FALSE, 17},
129
130         { "gnu-barcode", "EAN-8", N_("EAN-8"), gl_barcode_gnubarcode_new,
131           TRUE, TRUE, TRUE, FALSE, "0000000", FALSE, 7},
132
133         { "gnu-barcode", "EAN-8+2", N_("EAN-8 +2"), gl_barcode_gnubarcode_new,
134           TRUE, TRUE, TRUE, FALSE, "0000000 00", FALSE, 9},
135
136         { "gnu-barcode", "EAN-8+5", N_("EAN-8 +5"), gl_barcode_gnubarcode_new,
137           TRUE, TRUE, TRUE, FALSE, "0000000 00000", FALSE, 12},
138
139         { "gnu-barcode", "EAN-13", N_("EAN-13"), gl_barcode_gnubarcode_new,
140           TRUE, TRUE, TRUE, FALSE, "000000000000", FALSE, 12},
141
142         { "gnu-barcode", "EAN-13+2", N_("EAN-13 +2"), gl_barcode_gnubarcode_new,
143           TRUE, TRUE, TRUE, FALSE, "000000000000 00", FALSE, 14},
144
145         { "gnu-barcode", "EAN-13+5", N_("EAN-13 +5"), gl_barcode_gnubarcode_new,
146           TRUE, TRUE, TRUE, FALSE, "000000000000 00000", FALSE, 17},
147
148         { "gnu-barcode", "UPC", N_("UPC (UPC-A or UPC-E)"), gl_barcode_gnubarcode_new,
149           TRUE, TRUE, TRUE, FALSE, "00000000000 00000", FALSE, 16},
150
151         { "gnu-barcode", "UPC-A", N_("UPC-A"), gl_barcode_gnubarcode_new,
152           TRUE, TRUE, TRUE, FALSE, "00000000000", FALSE, 11},
153
154         { "gnu-barcode", "UPC-A+2", N_("UPC-A +2"), gl_barcode_gnubarcode_new,
155           TRUE, TRUE, TRUE, FALSE, "00000000000 00", FALSE, 13},
156
157         { "gnu-barcode", "UPC-A+5", N_("UPC-A +5"), gl_barcode_gnubarcode_new,
158           TRUE, TRUE, TRUE, FALSE, "00000000000 00000", FALSE, 16},
159
160         { "gnu-barcode", "UPC-E", N_("UPC-E"), gl_barcode_gnubarcode_new,
161           TRUE, TRUE, TRUE, FALSE, "000000", FALSE, 6},
162
163         { "gnu-barcode", "UPC-E+2", N_("UPC-E +2"), gl_barcode_gnubarcode_new,
164           TRUE, TRUE, TRUE, FALSE, "000000 00", FALSE, 8},
165
166         { "gnu-barcode", "UPC-E+5", N_("UPC-E +5"), gl_barcode_gnubarcode_new,
167           TRUE, TRUE, TRUE, FALSE, "000000 00000", FALSE, 11},
168
169         { "gnu-barcode", "ISBN", N_("ISBN"), gl_barcode_gnubarcode_new,
170           TRUE, TRUE, TRUE, TRUE, "0-00000-000-0", FALSE, 10},
171
172         { "gnu-barcode", "ISBN+5", N_("ISBN +5"), gl_barcode_gnubarcode_new,
173           TRUE, TRUE, TRUE, TRUE, "0-00000-000-0 00000", FALSE, 15},
174
175         { "gnu-barcode", "Code39", N_("Code 39"), gl_barcode_gnubarcode_new,
176           TRUE, TRUE, TRUE, TRUE, "0000000000", TRUE, 10},
177
178         { "gnu-barcode", "Code128", N_("Code 128"), gl_barcode_gnubarcode_new,
179           TRUE, TRUE, TRUE, TRUE, "0000000000", TRUE, 10},
180
181         { "gnu-barcode", "Code128C", N_("Code 128C"), gl_barcode_gnubarcode_new,
182           TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
183
184         { "gnu-barcode", "Code128B", N_("Code 128B"), gl_barcode_gnubarcode_new,
185           TRUE, TRUE, TRUE, TRUE, "0000000000", TRUE, 10},
186
187         { "gnu-barcode", "I25", N_("Interleaved 2 of 5"), gl_barcode_gnubarcode_new,
188           TRUE, TRUE, TRUE, TRUE, "0000000000", TRUE, 10},
189
190         { "gnu-barcode", "CBR", N_("Codabar"), gl_barcode_gnubarcode_new,
191           TRUE, TRUE, TRUE, TRUE, "0000000000", TRUE, 10},
192
193         { "gnu-barcode", "MSI", N_("MSI"), gl_barcode_gnubarcode_new,
194           TRUE, TRUE, TRUE, TRUE, "0000000000", TRUE, 10},
195
196         { "gnu-barcode", "PLS", N_("Plessey"), gl_barcode_gnubarcode_new,
197           TRUE, TRUE, TRUE, TRUE, "0000000000", TRUE, 10},
198
199         { "gnu-barcode", "Code93", N_("Code 93"), gl_barcode_gnubarcode_new,
200           TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
201
202 #endif /* HAVE_LIBBARCODE */
203
204 #ifdef HAVE_LIBZINT
205
206         { "zint", "AUSP", N_("Australia Post Standard"), gl_barcode_zint_new,
207           FALSE, FALSE, TRUE, FALSE, "12345678901234567890123", TRUE, 23},
208
209         { "zint", "AUSRP", N_("Australia Post Reply Paid"), gl_barcode_zint_new,
210           FALSE, FALSE, TRUE, FALSE, "12345678", TRUE, 8},
211
212         { "zint", "AUSRT", N_("Australia Post Route Code"), gl_barcode_zint_new,
213           FALSE, FALSE, TRUE, FALSE, "12345678", TRUE, 8},
214
215         { "zint", "AUSRD", N_("Australia Post Redirect"), gl_barcode_zint_new,
216           FALSE, FALSE, TRUE, FALSE, "12345678", TRUE, 8},
217
218         { "zint", "AZTEC", N_("Aztec Code"), gl_barcode_zint_new,
219           FALSE, FALSE, TRUE, FALSE, "1234567890", TRUE, 10},
220           
221         { "zint", "AZRUN", N_("Aztec Rune"), gl_barcode_zint_new,
222           FALSE, FALSE, TRUE, FALSE, "255", TRUE, 3},
223
224         { "zint", "CBR", N_("Codabar"), gl_barcode_zint_new,
225           TRUE, TRUE, TRUE, FALSE, "ABCDABCDAB", TRUE, 10},
226
227         { "zint", "Code1", N_("Code One"),  gl_barcode_zint_new,
228           FALSE, FALSE, TRUE, FALSE, "0000000000", TRUE, 10},
229
230         { "zint", "Code11", N_("Code 11"), gl_barcode_zint_new,
231           TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
232           
233         { "zint", "C16K", N_("Code 16K"), gl_barcode_zint_new,
234           FALSE, FALSE, TRUE, FALSE, "0000000000", TRUE, 10},
235           
236         { "zint", "C25M", N_("Code 2 of 5 Matrix"),  gl_barcode_zint_new,
237           TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
238           
239         { "zint", "C25I", N_("Code 2 of 5 IATA"),  gl_barcode_zint_new,
240           TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
241           
242         { "zint", "C25DL", N_("Code 2 of 5 Data Logic"),  gl_barcode_zint_new,
243           TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
244
245         { "zint", "Code32", N_("Code 32 (Italian Pharmacode)"),  gl_barcode_zint_new,
246           TRUE, TRUE, TRUE, FALSE, "12345678", TRUE, 8},
247
248         { "zint", "Code39", N_("Code 39"), gl_barcode_zint_new,
249           TRUE, TRUE, FALSE, FALSE, "0000000000", TRUE, 10},
250           
251         { "zint", "Code39E", N_("Code 39 Extended"),  gl_barcode_zint_new,
252           TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
253
254         { "zint", "Code49", N_("Code 49"), gl_barcode_zint_new,
255           FALSE, FALSE, TRUE, FALSE, "0000000000", TRUE, 10},
256
257         { "zint", "Code93", N_("Code 93"), gl_barcode_zint_new,
258           TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
259
260         { "zint", "Code128", N_("Code 128"), gl_barcode_zint_new,
261           TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
262           
263         { "zint", "Code128B", N_("Code 128 (Mode C suppression)"), gl_barcode_zint_new,
264           TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
265           
266         { "zint", "DAFT", N_("DAFT Code"), gl_barcode_zint_new,
267           FALSE, FALSE, FALSE, FALSE, "DAFTDAFTDAFTDAFT", TRUE, 16},
268
269         { "zint", "DMTX", N_("Data Matrix"), gl_barcode_zint_new,
270           FALSE, FALSE, TRUE, FALSE, "0000000000", TRUE, 10},
271
272         { "zint", "DMTX-GS1", N_("Data Matrix (GS1)"), gl_barcode_zint_new,
273           FALSE, FALSE, TRUE, FALSE, "0000000000", TRUE, 10},
274
275         { "zint", "DPL", N_("Deutsche Post Leitcode"), gl_barcode_zint_new,
276           TRUE, TRUE, TRUE, FALSE, "1234567890123", TRUE, 13},
277           
278         { "zint", "DPI", N_("Deutsche Post Identcode"), gl_barcode_zint_new,
279           TRUE, TRUE, TRUE, FALSE, "12345678901", TRUE, 11},
280           
281         { "zint", "KIX", N_("Dutch Post KIX Code"), gl_barcode_zint_new,
282           FALSE, FALSE, TRUE, FALSE, "0000000000", TRUE, 10},
283
284         { "zint", "EAN", N_("EAN"), gl_barcode_zint_new,
285           TRUE, TRUE, TRUE, FALSE, "1234567890123", FALSE, 13},
286
287         { "zint", "GMTX", N_("Grid Matrix"),  gl_barcode_zint_new,
288           FALSE, FALSE, TRUE, FALSE, "0000000000", TRUE, 10},
289
290         { "zint", "GS1-128", N_("GS1-128"), gl_barcode_zint_new,
291           TRUE, TRUE, TRUE, FALSE, "[01]12345678901234", FALSE, 18},
292
293         { "zint", "RSS14", N_("GS1 DataBar-14"), gl_barcode_zint_new,
294           TRUE, TRUE, TRUE, FALSE, "1234567890123", TRUE, 13},
295           
296         { "zint", "RSSLTD", "GS1 DataBar-14 Limited",  gl_barcode_zint_new,
297           TRUE, TRUE, TRUE, FALSE, "1234567890123", TRUE, 13},
298           
299         { "zint", "RSSEXP", "GS1 DataBar Extended",  gl_barcode_zint_new,
300           TRUE, TRUE, TRUE, FALSE, "[01]12345678901234", FALSE, 18},
301           
302         { "zint", "RSSS", N_("GS1 DataBar-14 Stacked"), gl_barcode_zint_new,
303           FALSE, FALSE, TRUE, FALSE, "0000000000", TRUE, 10},
304
305         { "zint", "RSSSO", N_("GS1 DataBar-14 Stacked Omni."), gl_barcode_zint_new,
306           FALSE, FALSE, TRUE, FALSE, "0000000000", TRUE, 10},
307
308         { "zint", "RSSSE", N_("GS1 DataBar Extended Stacked"), gl_barcode_zint_new,
309           FALSE, FALSE, TRUE, FALSE, "[01]12345678901234", FALSE, 18},
310
311         { "zint", "HIBC128", N_("HIBC Code 128"), gl_barcode_zint_new,
312           TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
313
314         { "zint", "HIBC39", N_("HIBC Code 39"), gl_barcode_zint_new,
315           TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
316
317         { "zint", "HIBCDM", N_("HIBC Data Matrix"), gl_barcode_zint_new,
318           FALSE, FALSE, TRUE, FALSE, "0000000000", TRUE, 10},
319
320         { "zint", "HIBCQR", N_("HIBC QR Code"), gl_barcode_zint_new,
321           FALSE, FALSE, TRUE, FALSE, "0000000000", TRUE, 10},
322
323         { "zint", "HIBCPDF", N_("HIBC PDF417"), gl_barcode_zint_new,
324           FALSE, FALSE, TRUE, FALSE, "0000000000", TRUE, 10},
325
326         { "zint", "HIBCMPDF", N_("HIBC Micro PDF417"), gl_barcode_zint_new,
327           FALSE, FALSE, TRUE, FALSE, "0000000000", TRUE, 10},
328
329         { "zint", "HIBCAZ", N_("HIBC Aztec Code"), gl_barcode_zint_new,
330           TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
331
332         { "zint", "I25", N_("Interleaved 2 of 5"), gl_barcode_zint_new,
333           TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
334
335         { "zint", "ISBN", N_("ISBN"), gl_barcode_zint_new,
336           TRUE, TRUE, TRUE, FALSE, "123456789", FALSE, 9},
337
338         { "zint", "ITF14", N_("ITF-14"), gl_barcode_zint_new,
339           TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
340
341         { "zint", "JAPAN", N_("Japanese Postal"), gl_barcode_zint_new,
342           FALSE, FALSE, TRUE, FALSE, "0000000000", TRUE, 10},
343
344         { "zint", "KOREA", N_("Korean Postal"), gl_barcode_zint_new,
345           TRUE, TRUE, TRUE, FALSE, "123456", FALSE, 6},
346
347         { "zint", "LOGM", N_("LOGMARS"), gl_barcode_zint_new,
348           TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
349
350         { "zint", "MAXI", N_("Maxicode"), gl_barcode_zint_new,
351           FALSE, FALSE, FALSE, FALSE, "0000000000", TRUE, 10},
352
353         { "zint", "MPDF", N_("Micro PDF417"), gl_barcode_zint_new,
354           FALSE, FALSE, TRUE, FALSE, "0000000000", TRUE, 10},
355
356         { "zint", "MQR", N_("Micro QR Code"), gl_barcode_zint_new,
357           FALSE, FALSE, TRUE, FALSE, "0000000000", TRUE, 10},
358
359         { "zint", "MSI", N_("MSI Plessey"), gl_barcode_zint_new,
360           TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
361
362         { "zint", "NVE", N_("NVE-18"), gl_barcode_zint_new,
363           TRUE, TRUE, TRUE, FALSE, "12345678901234567", FALSE, 17},
364
365         { "zint", "PDF", N_("PDF417"), gl_barcode_zint_new,
366           FALSE, FALSE, TRUE, FALSE, "0000000000", TRUE, 10},
367
368         { "zint", "PDFT", N_("PDF417 Truncated"), gl_barcode_zint_new,
369           FALSE, FALSE, TRUE, FALSE, "0000000000", TRUE, 10},
370
371         { "zint", "PLAN", N_("PLANET"), gl_barcode_zint_new,
372           FALSE, FALSE, TRUE, FALSE, "0000000000", TRUE, 10},
373
374         { "zint", "POSTNET", N_("PostNet"), gl_barcode_zint_new,
375           TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
376
377         { "zint", "PHARMA", N_("Pharmacode"), gl_barcode_zint_new,
378           FALSE, FALSE, TRUE, FALSE, "123456", FALSE, 6},
379
380         { "zint", "PHARMA2", N_("Pharmacode 2-track"), gl_barcode_zint_new,
381           FALSE, FALSE, TRUE, FALSE, "12345678", FALSE, 8},
382
383         { "zint", "PZN", N_("Pharmazentral Nummer (PZN)"), gl_barcode_zint_new,
384           TRUE, TRUE, TRUE, FALSE, "123456", FALSE, 6},
385
386         { "zint", "QR", N_("QR Code"), gl_barcode_zint_new,
387           TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
388
389         { "zint", "RM4", N_("Royal Mail 4-State"), gl_barcode_zint_new,
390           FALSE, FALSE, TRUE, FALSE, "0000000000", TRUE, 10},
391
392         { "zint", "TELE", N_("Telepen"), gl_barcode_zint_new,
393           TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
394
395         { "zint", "TELEX", N_("Telepen Numeric"), gl_barcode_zint_new,
396           TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
397
398         { "zint", "UPC-A", N_("UPC-A"),  gl_barcode_zint_new,
399           TRUE, TRUE, TRUE, FALSE, "12345678901", FALSE, 11},
400           
401         { "zint", "UPC-E", N_("UPC-E"),  gl_barcode_zint_new,
402           TRUE, TRUE, TRUE, FALSE, "1234567", FALSE, 7},
403           
404         { "zint", "USPS", N_("USPS One Code"), gl_barcode_zint_new,
405           FALSE, FALSE, TRUE, FALSE, "12345678901234567890", TRUE, 20},
406
407         { "zint", "PLS", N_("UK Plessey"), gl_barcode_zint_new,
408           TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
409
410 #endif /* HAVE_LIBZINT */
411
412 #ifdef HAVE_LIBIEC16022
413
414         { "libiec16022", "IEC16022", N_("IEC16022 (DataMatrix)"), gl_barcode_iec16022_new,
415           FALSE, FALSE, TRUE, FALSE, "12345678", TRUE, 8},
416
417 #endif /* HAVE_LIBIEC16022 */
418
419 #ifdef HAVE_LIBQRENCODE
420
421         { "libqrencode", "IEC18004", N_("IEC18004 (QRCode)"), gl_barcode_iec18004_new,
422           FALSE, FALSE, TRUE, FALSE, "12345678", TRUE, 8},
423
424 #endif /* HAVE_LIBQRENCODE */
425
426         { NULL, NULL, NULL, NULL, FALSE, FALSE, FALSE, FALSE, NULL, FALSE, 0}
427
428 };
429
430
431 /*========================================================*/
432 /* Private function prototypes.                           */
433 /*========================================================*/
434
435 static gint backend_id_to_index   (const gchar *id);
436 static gint backend_name_to_index (const gchar *name);
437 static gint style_id_to_index     (const gchar *backend_id,
438                                    const gchar *id);
439 static gint style_name_to_index   (const gchar *backend_id,
440                                    const gchar *name);
441
442 /*---------------------------------------------------------------------------*/
443 /* Convert backend id to index into backends table.                          */
444 /*---------------------------------------------------------------------------*/
445 static gint
446 backend_id_to_index (const gchar *id)
447 {
448         gint i;
449
450         if (id == NULL)
451         {
452                 return 0; /* NULL request default. I.e., the first element. */
453         }
454
455         for (i=0; styles[i].id != NULL; i++)
456         {
457                 if (g_ascii_strcasecmp (id, backends[i].id) == 0)
458                 {
459                         return i;
460                 }
461         }
462
463         g_message( "Unknown barcode id \"%s\"", id );
464         return 0;
465 }
466
467
468 /*---------------------------------------------------------------------------*/
469 /* Convert backend name to index into backends table.                        */
470 /*---------------------------------------------------------------------------*/
471 static gint
472 backend_name_to_index (const gchar *name)
473 {
474         gint i;
475
476         if (name == NULL)
477         {
478                 return 0; /* NULL request default. I.e., the first element. */
479         }
480
481         for (i=0; styles[i].id != NULL; i++)
482         {
483                 if (strcmp (name, gettext (backends[i].name)) == 0)
484                 {
485                         return i;
486                 }
487         }
488
489         g_message( "Unknown barcode name \"%s\"", name );
490         return 0;
491 }
492
493
494 /*---------------------------------------------------------------------------*/
495 /* Convert style id to index into styles table.                              */
496 /*---------------------------------------------------------------------------*/
497 static gint
498 style_id_to_index (const gchar *backend_id,
499                    const gchar *id)
500 {
501         gint i;
502
503         if (backend_id == NULL)
504         {
505                 return 0; /* NULL request default. I.e., the first element. */
506         }
507
508         if (id == NULL)
509         {
510                 /* Search for first element with given backend_id. */
511                 for (i=0; styles[i].id != NULL; i++)
512                 {
513                         if (g_ascii_strcasecmp (backend_id, styles[i].backend_id) == 0)
514                         {
515                                 return i;
516                         }
517                 }
518                 g_message( "Unknown barcode backend id \"%s\"", backend_id );
519                 return 0;
520         }
521
522         for (i=0; styles[i].id != NULL; i++)
523         {
524                 if ((g_ascii_strcasecmp (backend_id, styles[i].backend_id) == 0) &&
525                     (g_ascii_strcasecmp (id, styles[i].id) == 0))
526                 {
527                         return i;
528                 }
529         }
530
531         g_message( "Unknown barcode id \"%s\"", id );
532         return 0;
533 }
534
535
536 /*---------------------------------------------------------------------------*/
537 /* Convert style name to index into styles table.                            */
538 /*---------------------------------------------------------------------------*/
539 static gint
540 style_name_to_index (const gchar *backend_id,
541                      const gchar *name)
542 {
543         gint i;
544
545         if (backend_id == NULL)
546         {
547                 return 0; /* NULL request default. I.e., the first element. */
548         }
549
550         if (name == NULL)
551         {
552                 /* Search for first element with given backend_id. */
553                 for (i=0; styles[i].id != NULL; i++)
554                 {
555                         if (g_ascii_strcasecmp (backend_id, styles[i].backend_id) == 0)
556                         {
557                                 return i;
558                         }
559                 }
560                 g_message( "Unknown barcode backend id \"%s\"", backend_id );
561                 return 0;
562         }
563
564         for (i=0; styles[i].id != NULL; i++)
565         {
566                 if ((g_ascii_strcasecmp (backend_id, styles[i].backend_id) == 0) &&
567                     (strcmp (name, gettext (styles[i].name)) == 0))
568                 {
569                         return i;
570                 }
571         }
572
573         g_message( "Unknown barcode name \"%s\"", name );
574         return 0;
575 }
576
577
578 /*****************************************************************************/
579 /* Get a list of names for configured backends.                              */
580 /*****************************************************************************/
581 GList *
582 gl_barcode_backends_get_backend_list (void)
583 {
584         gint   i;
585         GList *list = NULL;
586
587         for (i=0; backends[i].id != NULL; i++)
588         {
589                 list = g_list_prepend (list, g_strdup (gettext (backends[i].name)));
590         }
591
592         return g_list_reverse (list);
593 }
594
595
596 /*****************************************************************************/
597 /* Free up a previously allocated list of backend names.                     */
598 /*****************************************************************************/
599 void
600 gl_barcode_backends_free_backend_list (GList *backend_list)
601 {
602         GList *p;
603
604         for (p=backend_list; p != NULL; p=p->next)
605         {
606                 g_free (p->data);
607                 p->data = NULL;
608         }
609
610         g_list_free (backend_list);
611 }
612
613
614 /*****************************************************************************/
615 /* Convert backend id to name.                                               */
616 /*****************************************************************************/
617 const gchar *
618 gl_barcode_backends_backend_id_to_name (const gchar *backend_id)
619 {
620         return gettext (backends[backend_id_to_index (backend_id)].name);
621 }
622
623
624 /*****************************************************************************/
625 /* Convert backend name to id.                                               */
626 /*****************************************************************************/
627 const gchar *
628 gl_barcode_backends_backend_name_to_id (const gchar *backend_name)
629 {
630         return backends[backend_name_to_index (backend_name)].id;
631 }
632
633
634 /*****************************************************************************/
635 /* Test if backend id is valid.                                              */
636 /*****************************************************************************/
637 gboolean
638 gl_barcode_backends_is_backend_id_valid (const gchar    *backend_id)
639 {
640         gint i;
641
642         if (backend_id == NULL)
643         {
644                 return FALSE;
645         }
646
647         for (i=0; backends[i].id != NULL; i++)
648         {
649                 if (g_ascii_strcasecmp (backend_id, backends[i].id) == 0)
650                 {
651                         return TRUE;
652                 }
653         }
654
655         return FALSE;
656 }
657
658
659 /*****************************************************************************/
660 /* Guess backend id from style id (for backwards compatability).             */
661 /*****************************************************************************/
662 const gchar *
663 gl_barcode_backends_guess_backend_id (const gchar *id)
664 {
665         gint i;
666
667         if (id == NULL)
668         {
669                 return styles[0].backend_id;
670         }
671
672         for (i=0; styles[i].id != NULL; i++)
673         {
674                 if (g_ascii_strcasecmp (id, styles[i].id) == 0)
675                 {
676                         return styles[i].backend_id;
677                 }
678         }
679
680         g_message( "Unknown barcode id \"%s\"", id );
681         return styles[0].backend_id;
682 }
683
684
685 /*****************************************************************************/
686 /* Get a list of names for valid barcode styles.                             */
687 /*****************************************************************************/
688 GList *
689 gl_barcode_backends_get_styles_list  (const gchar *backend_id)
690 {
691         gint   i;
692         GList *list = NULL;
693
694         for (i=0; styles[i].id != NULL; i++)
695         {
696                 if ( g_ascii_strcasecmp (styles[i].backend_id, backend_id) == 0 )
697                 {
698                         list = g_list_prepend (list, g_strdup (gettext (styles[i].name)));
699                 }
700         }
701
702         return g_list_reverse (list);
703 }
704
705
706 /*****************************************************************************/
707 /* Free up a previously allocated list of style names.                       */
708 /*****************************************************************************/
709 void
710 gl_barcode_backends_free_styles_list (GList *styles_list)
711 {
712         GList *p;
713
714         for (p=styles_list; p != NULL; p=p->next)
715         {
716                 g_free (p->data);
717                 p->data = NULL;
718         }
719
720         g_list_free (styles_list);
721 }
722
723
724 /*****************************************************************************/
725 /* Convert style to text.                                                    */
726 /*****************************************************************************/
727 const gchar *
728 gl_barcode_backends_style_id_to_name (const gchar *backend_id,
729                                       const gchar *id)
730 {
731         return gettext (styles[style_id_to_index (backend_id, id)].name);
732 }
733
734
735 /*****************************************************************************/
736 /* Convert name to style.                                                    */
737 /*****************************************************************************/
738 const gchar *
739 gl_barcode_backends_style_name_to_id (const gchar *backend_id,
740                                       const gchar *name)
741 {
742         return styles[style_name_to_index (backend_id, name)].id;
743 }
744
745
746 /*****************************************************************************/
747 /* Return an appropriate set of digits for the given barcode style.          */
748 /*****************************************************************************/
749 gchar *
750 gl_barcode_backends_style_default_digits (const gchar *backend_id,
751                                           const gchar *id,
752                                           guint        n)
753 {
754         int i;
755
756         i = style_id_to_index (backend_id, id);
757
758         if (styles[i].can_freeform)
759         {
760                 return g_strnfill (MAX (n,1), '0');
761         }
762         else
763         {
764                 return g_strdup (styles[i].default_digits);
765         }
766 }
767
768
769 /*****************************************************************************/
770 /* Query text capabilities.                                                  */
771 /*****************************************************************************/
772 gboolean
773 gl_barcode_backends_style_can_text (const gchar *backend_id,
774                                     const gchar *id)
775 {
776         return styles[style_id_to_index (backend_id, id)].can_text;
777 }
778
779
780 gboolean
781 gl_barcode_backends_style_text_optional (const gchar *backend_id,
782                                          const gchar *id)
783 {
784         return styles[style_id_to_index (backend_id, id)].text_optional;
785 }
786
787
788 /*****************************************************************************/
789 /* Query checksum capabilities.                                              */
790 /*****************************************************************************/
791 gboolean
792 gl_barcode_backends_style_can_csum (const gchar *backend_id,
793                                     const gchar *id)
794 {
795         return styles[style_id_to_index (backend_id, id)].can_checksum;
796 }
797
798
799 gboolean
800 gl_barcode_backends_style_csum_optional (const gchar *backend_id,
801                                          const gchar *id)
802 {
803         return styles[style_id_to_index (backend_id, id)].checksum_optional;
804 }
805
806
807 /*****************************************************************************/
808 /* Query if freeform input is allowed.                                       */
809 /*****************************************************************************/
810 gboolean
811 gl_barcode_backends_style_can_freeform (const gchar *backend_id,
812                                         const gchar    *id)
813 {
814         return styles[style_id_to_index (backend_id, id)].can_freeform;
815 }
816
817
818 /*****************************************************************************/
819 /* Query prefered number of digits of input.                                 */
820 /*****************************************************************************/
821 guint
822 gl_barcode_backends_style_get_prefered_n (const gchar *backend_id,
823                                           const gchar *id)
824 {
825         return styles[style_id_to_index (backend_id, id)].prefered_n;
826 }
827
828
829 /*****************************************************************************/
830 /* Call appropriate barcode backend to create barcode in intermediate format.*/
831 /*****************************************************************************/
832 lglBarcode *
833 gl_barcode_backends_new_barcode (const gchar    *backend_id,
834                                  const gchar    *id,
835                                  gboolean        text_flag,
836                                  gboolean        checksum_flag,
837                                  gdouble         w,
838                                  gdouble         h,
839                                  const gchar    *digits)
840 {
841         lglBarcode *gbc;
842         gint        i;
843
844         g_return_val_if_fail (digits!=NULL, NULL);
845
846         i = style_id_to_index (backend_id, id);
847
848         gbc = styles[i].new_barcode (styles[i].id,
849                                      text_flag,
850                                      checksum_flag,
851                                      w,
852                                      h,
853                                      digits);
854
855         return gbc;
856 }
857
858
859
860 /*
861  * Local Variables:       -- emacs
862  * mode: C                -- emacs
863  * c-basic-offset: 8      -- emacs
864  * tab-width: 8           -- emacs
865  * indent-tabs-mode: nil  -- emacs
866  * End:                   -- emacs
867  */