]> git.sur5r.net Git - glabels/blob - glabels2/src/bc.c
2004-02-15 Jim Evins <evins@snaught.com>
[glabels] / glabels2 / src / bc.c
1 /*
2  *  (GLABELS) Label and Business Card Creation program for GNOME
3  *
4  *  bc.c:  GLabels barcode module
5  *
6  *  Copyright (C) 2001-2003  Jim Evins <evins@snaught.com>.
7  *
8  *  This program is free software; you can redistribute it and/or modify
9  *  it under the terms of the GNU General Public License as published by
10  *  the Free Software Foundation; either version 2 of the License, or
11  *  (at your option) any later version.
12  *
13  *  This program is distributed in the hope that it will be useful,
14  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  *  GNU General Public License for more details.
17  *
18  *  You should have received a copy of the GNU General Public License
19  *  along with this program; if not, write to the Free Software
20  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
21  */
22 #include <config.h>
23
24 #include <libgnome/libgnome.h>
25
26 #include "bc.h"
27 #include "bc-postnet.h"
28 #include "bc-gnubarcode.h"
29
30 #include "debug.h"
31
32 /*========================================================*/
33 /* Private macros and constants.                          */
34 /*========================================================*/
35
36 /*========================================================*/
37 /* Private types.                                         */
38 /*========================================================*/
39
40 typedef struct {
41         gchar            *id;
42         gchar            *name;
43         glBarcodeNewFunc  new;
44         gboolean          can_text;
45         gboolean          text_optional;
46         gboolean          can_checksum;
47         gboolean          checksum_optional;
48         gchar            *default_digits;
49 } Backend;
50
51
52 /*========================================================*/
53 /* Private globals.                                       */
54 /*========================================================*/
55
56 Backend backends[] = {
57
58         { "POSTNET", N_("POSTNET (any)"), gl_barcode_postnet_new,
59           FALSE, FALSE, TRUE, FALSE, "000000000"},
60
61         { "POSTNET-5", N_("POSTNET-5 (ZIP only)"), gl_barcode_postnet_new,
62           FALSE, FALSE, TRUE, FALSE, "00000"},
63
64         { "POSTNET-9", N_("POSTNET-9 (ZIP+4)"), gl_barcode_postnet_new,
65           FALSE, FALSE, TRUE, FALSE, "000000000"},
66
67         { "POSTNET-11", N_("POSTNET-11 (DPBC)"), gl_barcode_postnet_new,
68           FALSE, FALSE, TRUE, FALSE, "00000000000"},
69
70         { "EAN", N_("EAN (any)"), gl_barcode_gnubarcode_new,
71           TRUE, TRUE, TRUE, FALSE, "000000000000 00000"},
72
73         { "EAN-8", N_("EAN-8"), gl_barcode_gnubarcode_new,
74           TRUE, TRUE, TRUE, FALSE, "0000000"},
75
76         { "EAN-8+2", N_("EAN-8 +2"), gl_barcode_gnubarcode_new,
77           TRUE, TRUE, TRUE, FALSE, "0000000 00"},
78
79         { "EAN-8+5", N_("EAN-8 +5"), gl_barcode_gnubarcode_new,
80           TRUE, TRUE, TRUE, FALSE, "0000000 00000"},
81
82         { "EAN-13", N_("EAN-13"), gl_barcode_gnubarcode_new,
83           TRUE, TRUE, TRUE, FALSE, "000000000000"},
84
85         { "EAN-13+2", N_("EAN-13 +2"), gl_barcode_gnubarcode_new,
86           TRUE, TRUE, TRUE, FALSE, "000000000000 00"},
87
88         { "EAN-13+5", N_("EAN-13 +5"), gl_barcode_gnubarcode_new,
89           TRUE, TRUE, TRUE, FALSE, "000000000000 00000"},
90
91         { "UPC", N_("UPC (UPC-A or UPC-E)"), gl_barcode_gnubarcode_new,
92           TRUE, TRUE, TRUE, FALSE, "00000000000 00000"},
93
94         { "UPC-A", N_("UPC-A"), gl_barcode_gnubarcode_new,
95           TRUE, TRUE, TRUE, FALSE, "00000000000"},
96
97         { "UPC-A+2", N_("UPC-A +2"), gl_barcode_gnubarcode_new,
98           TRUE, TRUE, TRUE, FALSE, "00000000000 00"},
99
100         { "UPC-A+5", N_("UPC-A +5"), gl_barcode_gnubarcode_new,
101           TRUE, TRUE, TRUE, FALSE, "00000000000 00000"},
102
103         { "UPC-E", N_("UPC-E"), gl_barcode_gnubarcode_new,
104           TRUE, TRUE, TRUE, FALSE, "000000"},
105
106         { "UPC-E+2", N_("UPC-E +2"), gl_barcode_gnubarcode_new,
107           TRUE, TRUE, TRUE, FALSE, "000000 00"},
108
109         { "UPC-E+5", N_("UPC-E +5"), gl_barcode_gnubarcode_new,
110           TRUE, TRUE, TRUE, FALSE, "000000 00000"},
111
112         { "ISBN", N_("ISBN"), gl_barcode_gnubarcode_new,
113           TRUE, TRUE, TRUE, TRUE, "0-00000-000-0"},
114
115         { "ISBN+5", N_("ISBN +5"), gl_barcode_gnubarcode_new,
116           TRUE, TRUE, TRUE, TRUE, "0-00000-000-0 00000"},
117
118         { "Code39", N_("Code 39"), gl_barcode_gnubarcode_new,
119           TRUE, TRUE, TRUE, TRUE, "0000000000"},
120
121         { "Code128", N_("Code 128"), gl_barcode_gnubarcode_new,
122           TRUE, TRUE, TRUE, TRUE, "0000000000"},
123
124         { "Code128C", N_("Code 128C"), gl_barcode_gnubarcode_new,
125           TRUE, TRUE, TRUE, TRUE, "0000000000"},
126
127         { "Code128B", N_("Code 128B"), gl_barcode_gnubarcode_new,
128           TRUE, TRUE, TRUE, TRUE, "0000000000"},
129
130         { "I25", N_("Interleaved 2 of 5"), gl_barcode_gnubarcode_new,
131           TRUE, TRUE, TRUE, TRUE, "0000000000"},
132
133         { "CBR", N_("Codabar"), gl_barcode_gnubarcode_new,
134           TRUE, TRUE, TRUE, TRUE, "0000000000"},
135
136         { "MSI", N_("MSI"), gl_barcode_gnubarcode_new,
137           TRUE, TRUE, TRUE, TRUE, "0000000000"},
138
139         { "PLS", N_("Plessey"), gl_barcode_gnubarcode_new,
140           TRUE, TRUE, TRUE, TRUE, "0000000000"},
141
142         { NULL, NULL, NULL, FALSE, FALSE, FALSE, FALSE, NULL}
143
144 };
145
146 /*========================================================*/
147 /* Private function prototypes.                           */
148 /*========================================================*/
149
150 \f
151 /*---------------------------------------------------------------------------*/
152 /* Convert id to index into above table.                                     */
153 /*---------------------------------------------------------------------------*/
154 static gint
155 id_to_index (const gchar *id)
156 {
157         gint i;
158
159         if (id == 0) {
160                 return 0; /* NULL request default. I.e., the first element. */
161         }
162
163         for (i=0; backends[i].id != NULL; i++) {
164                 if (g_strcasecmp (id, backends[i].id) == 0) {
165                         return i;
166                 }
167         }
168
169         g_warning( "Unknown barcode id \"%s\"", id );
170         return 0;
171 }
172
173 /*---------------------------------------------------------------------------*/
174 /* Convert name to index into above table.                                   */
175 /*---------------------------------------------------------------------------*/
176 static gint
177 name_to_index (const gchar *name)
178 {
179         gint i;
180
181         g_return_val_if_fail (name!=NULL, 0);
182
183         for (i=0; backends[i].id != NULL; i++) {
184                 if (g_strcasecmp (name, backends[i].name) == 0) {
185                         return i;
186                 }
187         }
188
189         g_warning( "Unknown barcode name \"%s\"", name );
190         return 0;
191 }
192
193 /*****************************************************************************/
194 /* Call appropriate barcode backend to create barcode in intermediate format.*/
195 /*****************************************************************************/
196 glBarcode *
197 gl_barcode_new (const gchar    *id,
198                 gboolean        text_flag,
199                 gboolean        checksum_flag,
200                 gdouble         w,
201                 gdouble         h,
202                 const gchar    *digits)
203 {
204         glBarcode *gbc;
205         gint       i;
206
207         g_return_val_if_fail (digits!=NULL, NULL);
208
209         i = id_to_index (id);
210         gbc = backends[i].new (backends[i].id,
211                                text_flag,
212                                checksum_flag,
213                                w,
214                                h,
215                                digits);
216
217         return gbc;
218 }
219
220 /*****************************************************************************/
221 /* Free previously created barcode.                                          */
222 /*****************************************************************************/
223 void
224 gl_barcode_free (glBarcode **gbc)
225 {
226         GList *p;
227
228         if (*gbc != NULL) {
229
230                 for (p = (*gbc)->lines; p != NULL; p = p->next) {
231                         g_free (p->data);
232                         p->data = NULL;
233                 }
234                 g_list_free ((*gbc)->lines);
235                 (*gbc)->lines = NULL;
236
237                 for (p = (*gbc)->chars; p != NULL; p = p->next) {
238                         g_free (p->data);
239                         p->data = NULL;
240                 }
241                 g_list_free ((*gbc)->chars);
242                 (*gbc)->chars = NULL;
243
244                 g_free (*gbc);
245                 *gbc = NULL;
246         }
247 }
248
249 /*****************************************************************************/
250 /* Get a list of names for valid barcode styles.                             */
251 /*****************************************************************************/
252 GList *
253 gl_barcode_get_styles_list  (void)
254 {
255         gint   i;
256         GList *list = NULL;
257
258         for (i=0; backends[i].id != NULL; i++) {
259                 list = g_list_append (list, g_strdup (backends[i].name));
260         }
261
262         return list;
263 }
264
265 /*****************************************************************************/
266 /* Free up a previously allocated list of style names.                       */
267 /*****************************************************************************/
268 void
269 gl_barcode_free_styles_list (GList *styles_list)
270 {
271         GList *p;
272
273         for (p=styles_list; p != NULL; p=p->next) {
274                 g_free (p->data);
275                 p->data = NULL;
276         }
277
278         g_list_free (styles_list);
279 }
280
281
282 /*****************************************************************************/
283 /* Return an appropriate set of digits for the given barcode style.          */
284 /*****************************************************************************/
285 gchar *
286 gl_barcode_default_digits (const gchar *id)
287 {
288         return g_strdup (backends[id_to_index (id)].default_digits);
289 }
290
291 /*****************************************************************************/
292 /* Query text capabilities.                                                  */
293 /*****************************************************************************/
294 gboolean
295 gl_barcode_can_text (const gchar *id)
296 {
297         return backends[id_to_index (id)].can_text;
298 }
299
300 gboolean
301 gl_barcode_text_optional (const gchar *id)
302 {
303         return backends[id_to_index (id)].text_optional;
304 }
305
306 /*****************************************************************************/
307 /* Query checksum capabilities.                                              */
308 /*****************************************************************************/
309 gboolean
310 gl_barcode_can_csum (const gchar *id)
311 {
312         return backends[id_to_index (id)].can_checksum;
313 }
314
315 gboolean
316 gl_barcode_csum_optional (const gchar *id)
317 {
318         return backends[id_to_index (id)].checksum_optional;
319 }
320
321 /*****************************************************************************/
322 /* Convert style to text.                                                    */
323 /*****************************************************************************/
324 const gchar *
325 gl_barcode_id_to_name (const gchar *id)
326 {
327         return backends[id_to_index (id)].name;
328 }
329
330 /*****************************************************************************/
331 /* Convert name to style.                                                    */
332 /*****************************************************************************/
333 const gchar *
334 gl_barcode_name_to_id (const gchar *name)
335 {
336         g_return_val_if_fail (name!=NULL, backends[0].id);
337
338         return backends[name_to_index (name)].id;
339 }