1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */
4 * (GLABELS) Label and Business Card Creation program for GNOME
6 * bc.c: GLabels barcode module
8 * Copyright (C) 2001-2003 Jim Evins <evins@snaught.com>.
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
28 #include <glib/gi18n.h>
29 #include <glib/gmem.h>
30 #include <glib/gstrfuncs.h>
31 #include <glib/gmessages.h>
33 #include "bc-postnet.h"
34 #include "bc-gnubarcode.h"
35 #include "bc-iec16022.h"
39 /*========================================================*/
40 /* Private macros and constants. */
41 /*========================================================*/
43 /*========================================================*/
45 /*========================================================*/
52 gboolean text_optional;
53 gboolean can_checksum;
54 gboolean checksum_optional;
55 gchar *default_digits;
56 gboolean can_freeform;
61 /*========================================================*/
62 /* Private globals. */
63 /*========================================================*/
65 static const Backend backends[] = {
67 { "POSTNET", N_("POSTNET (any)"), gl_barcode_postnet_new,
68 FALSE, FALSE, TRUE, FALSE, "12345-6789-12", FALSE, 11},
70 { "POSTNET-5", N_("POSTNET-5 (ZIP only)"), gl_barcode_postnet_new,
71 FALSE, FALSE, TRUE, FALSE, "12345", FALSE, 5},
73 { "POSTNET-9", N_("POSTNET-9 (ZIP+4)"), gl_barcode_postnet_new,
74 FALSE, FALSE, TRUE, FALSE, "12345-6789", FALSE, 9},
76 { "POSTNET-11", N_("POSTNET-11 (DPBC)"), gl_barcode_postnet_new,
77 FALSE, FALSE, TRUE, FALSE, "12345-6789-12", FALSE, 11},
79 { "CEPNET", N_("CEPNET"), gl_barcode_postnet_new,
80 FALSE, FALSE, TRUE, FALSE, "12345-678", FALSE, 8},
82 { "EAN", N_("EAN (any)"), gl_barcode_gnubarcode_new,
83 TRUE, TRUE, TRUE, FALSE, "000000000000 00000", FALSE, 17},
85 { "EAN-8", N_("EAN-8"), gl_barcode_gnubarcode_new,
86 TRUE, TRUE, TRUE, FALSE, "0000000", FALSE, 7},
88 { "EAN-8+2", N_("EAN-8 +2"), gl_barcode_gnubarcode_new,
89 TRUE, TRUE, TRUE, FALSE, "0000000 00", FALSE, 9},
91 { "EAN-8+5", N_("EAN-8 +5"), gl_barcode_gnubarcode_new,
92 TRUE, TRUE, TRUE, FALSE, "0000000 00000", FALSE, 12},
94 { "EAN-13", N_("EAN-13"), gl_barcode_gnubarcode_new,
95 TRUE, TRUE, TRUE, FALSE, "000000000000", FALSE, 12},
97 { "EAN-13+2", N_("EAN-13 +2"), gl_barcode_gnubarcode_new,
98 TRUE, TRUE, TRUE, FALSE, "000000000000 00", FALSE, 14},
100 { "EAN-13+5", N_("EAN-13 +5"), gl_barcode_gnubarcode_new,
101 TRUE, TRUE, TRUE, FALSE, "000000000000 00000", FALSE, 17},
103 { "UPC", N_("UPC (UPC-A or UPC-E)"), gl_barcode_gnubarcode_new,
104 TRUE, TRUE, TRUE, FALSE, "00000000000 00000", FALSE, 16},
106 { "UPC-A", N_("UPC-A"), gl_barcode_gnubarcode_new,
107 TRUE, TRUE, TRUE, FALSE, "00000000000", FALSE, 11},
109 { "UPC-A+2", N_("UPC-A +2"), gl_barcode_gnubarcode_new,
110 TRUE, TRUE, TRUE, FALSE, "00000000000 00", FALSE, 13},
112 { "UPC-A+5", N_("UPC-A +5"), gl_barcode_gnubarcode_new,
113 TRUE, TRUE, TRUE, FALSE, "00000000000 00000", FALSE, 16},
115 { "UPC-E", N_("UPC-E"), gl_barcode_gnubarcode_new,
116 TRUE, TRUE, TRUE, FALSE, "000000", FALSE, 6},
118 { "UPC-E+2", N_("UPC-E +2"), gl_barcode_gnubarcode_new,
119 TRUE, TRUE, TRUE, FALSE, "000000 00", FALSE, 8},
121 { "UPC-E+5", N_("UPC-E +5"), gl_barcode_gnubarcode_new,
122 TRUE, TRUE, TRUE, FALSE, "000000 00000", FALSE, 11},
124 { "ISBN", N_("ISBN"), gl_barcode_gnubarcode_new,
125 TRUE, TRUE, TRUE, TRUE, "0-00000-000-0", FALSE, 10},
127 { "ISBN+5", N_("ISBN +5"), gl_barcode_gnubarcode_new,
128 TRUE, TRUE, TRUE, TRUE, "0-00000-000-0 00000", FALSE, 15},
130 { "Code39", N_("Code 39"), gl_barcode_gnubarcode_new,
131 TRUE, TRUE, TRUE, TRUE, "0000000000", TRUE, 10},
133 { "Code128", N_("Code 128"), gl_barcode_gnubarcode_new,
134 TRUE, TRUE, TRUE, TRUE, "0000000000", TRUE, 10},
136 { "Code128C", N_("Code 128C"), gl_barcode_gnubarcode_new,
137 TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
139 { "Code128B", N_("Code 128B"), gl_barcode_gnubarcode_new,
140 TRUE, TRUE, TRUE, TRUE, "0000000000", TRUE, 10},
142 { "I25", N_("Interleaved 2 of 5"), gl_barcode_gnubarcode_new,
143 TRUE, TRUE, TRUE, TRUE, "0000000000", TRUE, 10},
145 { "CBR", N_("Codabar"), gl_barcode_gnubarcode_new,
146 TRUE, TRUE, TRUE, TRUE, "0000000000", TRUE, 10},
148 { "MSI", N_("MSI"), gl_barcode_gnubarcode_new,
149 TRUE, TRUE, TRUE, TRUE, "0000000000", TRUE, 10},
151 { "PLS", N_("Plessey"), gl_barcode_gnubarcode_new,
152 TRUE, TRUE, TRUE, TRUE, "0000000000", TRUE, 10},
154 { "IEC16022", N_("IEC16022 (DataMatrix)"), gl_barcode_iec16022_new,
155 FALSE, FALSE, TRUE, FALSE, "12345678", TRUE, 8},
157 { NULL, NULL, NULL, FALSE, FALSE, FALSE, FALSE, NULL, FALSE, 0}
161 /*========================================================*/
162 /* Private function prototypes. */
163 /*========================================================*/
166 /*---------------------------------------------------------------------------*/
167 /* Convert id to index into above table. */
168 /*---------------------------------------------------------------------------*/
170 id_to_index (const gchar *id)
175 return 0; /* NULL request default. I.e., the first element. */
178 for (i=0; backends[i].id != NULL; i++) {
179 if (g_strcasecmp (id, backends[i].id) == 0) {
184 g_message( "Unknown barcode id \"%s\"", id );
188 /*---------------------------------------------------------------------------*/
189 /* Convert name to index into above table. */
190 /*---------------------------------------------------------------------------*/
192 name_to_index (const gchar *name)
196 g_return_val_if_fail (name!=NULL, 0);
198 for (i=0; backends[i].id != NULL; i++) {
199 if (g_strcasecmp (name, backends[i].name) == 0) {
204 g_message( "Unknown barcode name \"%s\"", name );
208 /*****************************************************************************/
209 /* Call appropriate barcode backend to create barcode in intermediate format.*/
210 /*****************************************************************************/
212 gl_barcode_new (const gchar *id,
214 gboolean checksum_flag,
222 g_return_val_if_fail (digits!=NULL, NULL);
224 i = id_to_index (id);
225 gbc = backends[i].new (backends[i].id,
235 /*****************************************************************************/
236 /* Free previously created barcode. */
237 /*****************************************************************************/
239 gl_barcode_free (glBarcode **gbc)
245 for (p = (*gbc)->lines; p != NULL; p = p->next) {
249 g_list_free ((*gbc)->lines);
250 (*gbc)->lines = NULL;
252 for (p = (*gbc)->chars; p != NULL; p = p->next) {
256 g_list_free ((*gbc)->chars);
257 (*gbc)->chars = NULL;
264 /*****************************************************************************/
265 /* Get a list of names for valid barcode styles. */
266 /*****************************************************************************/
268 gl_barcode_get_styles_list (void)
273 for (i=0; backends[i].id != NULL; i++) {
274 list = g_list_append (list, g_strdup (backends[i].name));
280 /*****************************************************************************/
281 /* Free up a previously allocated list of style names. */
282 /*****************************************************************************/
284 gl_barcode_free_styles_list (GList *styles_list)
288 for (p=styles_list; p != NULL; p=p->next) {
293 g_list_free (styles_list);
297 /*****************************************************************************/
298 /* Return an appropriate set of digits for the given barcode style. */
299 /*****************************************************************************/
301 gl_barcode_default_digits (const gchar *id,
306 i = id_to_index (id);
308 if (backends[i].can_freeform) {
310 return g_strnfill (MAX (n,1), '0');
314 return g_strdup (backends[i].default_digits);
319 /*****************************************************************************/
320 /* Query text capabilities. */
321 /*****************************************************************************/
323 gl_barcode_can_text (const gchar *id)
325 return backends[id_to_index (id)].can_text;
329 gl_barcode_text_optional (const gchar *id)
331 return backends[id_to_index (id)].text_optional;
334 /*****************************************************************************/
335 /* Query checksum capabilities. */
336 /*****************************************************************************/
338 gl_barcode_can_csum (const gchar *id)
340 return backends[id_to_index (id)].can_checksum;
344 gl_barcode_csum_optional (const gchar *id)
346 return backends[id_to_index (id)].checksum_optional;
350 /*****************************************************************************/
351 /* Query if freeform input is allowed. */
352 /*****************************************************************************/
354 gl_barcode_can_freeform (const gchar *id)
356 return backends[id_to_index (id)].can_freeform;
359 /*****************************************************************************/
360 /* Query prefered number of digits of input. */
361 /*****************************************************************************/
363 gl_barcode_get_prefered_n (const gchar *id)
365 return backends[id_to_index (id)].prefered_n;
368 /*****************************************************************************/
369 /* Convert style to text. */
370 /*****************************************************************************/
372 gl_barcode_id_to_name (const gchar *id)
374 return backends[id_to_index (id)].name;
377 /*****************************************************************************/
378 /* Convert name to style. */
379 /*****************************************************************************/
381 gl_barcode_name_to_id (const gchar *name)
383 g_return_val_if_fail (name!=NULL, backends[0].id);
385 return backends[name_to_index (name)].id;