]> git.sur5r.net Git - glabels/blob - src/bc.c
Refactoring of barcode structure.
[glabels] / src / bc.c
1 /*
2  *  bc.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.h"
24
25 #include <glib.h>
26 #include <glib/gi18n.h>
27
28 #include "bc-postnet.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 struct {
47         gchar            *id;
48         gchar            *name;
49         glBarcodeNewFunc  new;
50         gboolean          can_text;
51         gboolean          text_optional;
52         gboolean          can_checksum;
53         gboolean          checksum_optional;
54         gchar            *default_digits;
55         gboolean          can_freeform;
56         guint             prefered_n;
57 } Backend;
58
59
60 /*========================================================*/
61 /* Private globals.                                       */
62 /*========================================================*/
63
64 static const Backend backends[] = {
65
66         { "POSTNET", N_("POSTNET (any)"), gl_barcode_postnet_new,
67           FALSE, FALSE, TRUE, FALSE, "12345-6789-12", FALSE, 11},
68
69         { "POSTNET-5", N_("POSTNET-5 (ZIP only)"), gl_barcode_postnet_new,
70           FALSE, FALSE, TRUE, FALSE, "12345", FALSE, 5},
71
72         { "POSTNET-9", N_("POSTNET-9 (ZIP+4)"), gl_barcode_postnet_new,
73           FALSE, FALSE, TRUE, FALSE, "12345-6789", FALSE, 9},
74
75         { "POSTNET-11", N_("POSTNET-11 (DPBC)"), gl_barcode_postnet_new,
76           FALSE, FALSE, TRUE, FALSE, "12345-6789-12", FALSE, 11},
77
78 #ifdef HAVE_LIBBARCODE
79
80         { "CEPNET", N_("CEPNET"), gl_barcode_postnet_new,
81           FALSE, FALSE, TRUE, FALSE, "12345-678", FALSE, 8},
82
83         { "EAN", N_("EAN (any)"), gl_barcode_gnubarcode_new,
84           TRUE, TRUE, TRUE, FALSE, "000000000000 00000", FALSE, 17},
85
86         { "EAN-8", N_("EAN-8"), gl_barcode_gnubarcode_new,
87           TRUE, TRUE, TRUE, FALSE, "0000000", FALSE, 7},
88
89         { "EAN-8+2", N_("EAN-8 +2"), gl_barcode_gnubarcode_new,
90           TRUE, TRUE, TRUE, FALSE, "0000000 00", FALSE, 9},
91
92         { "EAN-8+5", N_("EAN-8 +5"), gl_barcode_gnubarcode_new,
93           TRUE, TRUE, TRUE, FALSE, "0000000 00000", FALSE, 12},
94
95         { "EAN-13", N_("EAN-13"), gl_barcode_gnubarcode_new,
96           TRUE, TRUE, TRUE, FALSE, "000000000000", FALSE, 12},
97
98         { "EAN-13+2", N_("EAN-13 +2"), gl_barcode_gnubarcode_new,
99           TRUE, TRUE, TRUE, FALSE, "000000000000 00", FALSE, 14},
100
101         { "EAN-13+5", N_("EAN-13 +5"), gl_barcode_gnubarcode_new,
102           TRUE, TRUE, TRUE, FALSE, "000000000000 00000", FALSE, 17},
103
104         { "UPC", N_("UPC (UPC-A or UPC-E)"), gl_barcode_gnubarcode_new,
105           TRUE, TRUE, TRUE, FALSE, "00000000000 00000", FALSE, 16},
106
107         { "UPC-A", N_("UPC-A"), gl_barcode_gnubarcode_new,
108           TRUE, TRUE, TRUE, FALSE, "00000000000", FALSE, 11},
109
110         { "UPC-A+2", N_("UPC-A +2"), gl_barcode_gnubarcode_new,
111           TRUE, TRUE, TRUE, FALSE, "00000000000 00", FALSE, 13},
112
113         { "UPC-A+5", N_("UPC-A +5"), gl_barcode_gnubarcode_new,
114           TRUE, TRUE, TRUE, FALSE, "00000000000 00000", FALSE, 16},
115
116         { "UPC-E", N_("UPC-E"), gl_barcode_gnubarcode_new,
117           TRUE, TRUE, TRUE, FALSE, "000000", FALSE, 6},
118
119         { "UPC-E+2", N_("UPC-E +2"), gl_barcode_gnubarcode_new,
120           TRUE, TRUE, TRUE, FALSE, "000000 00", FALSE, 8},
121
122         { "UPC-E+5", N_("UPC-E +5"), gl_barcode_gnubarcode_new,
123           TRUE, TRUE, TRUE, FALSE, "000000 00000", FALSE, 11},
124
125         { "ISBN", N_("ISBN"), gl_barcode_gnubarcode_new,
126           TRUE, TRUE, TRUE, TRUE, "0-00000-000-0", FALSE, 10},
127
128         { "ISBN+5", N_("ISBN +5"), gl_barcode_gnubarcode_new,
129           TRUE, TRUE, TRUE, TRUE, "0-00000-000-0 00000", FALSE, 15},
130
131         { "Code39", N_("Code 39"), gl_barcode_gnubarcode_new,
132           TRUE, TRUE, TRUE, TRUE, "0000000000", TRUE, 10},
133
134         { "Code128", N_("Code 128"), gl_barcode_gnubarcode_new,
135           TRUE, TRUE, TRUE, TRUE, "0000000000", TRUE, 10},
136
137         { "Code128C", N_("Code 128C"), gl_barcode_gnubarcode_new,
138           TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
139
140         { "Code128B", N_("Code 128B"), gl_barcode_gnubarcode_new,
141           TRUE, TRUE, TRUE, TRUE, "0000000000", TRUE, 10},
142
143         { "I25", N_("Interleaved 2 of 5"), gl_barcode_gnubarcode_new,
144           TRUE, TRUE, TRUE, TRUE, "0000000000", TRUE, 10},
145
146         { "CBR", N_("Codabar"), gl_barcode_gnubarcode_new,
147           TRUE, TRUE, TRUE, TRUE, "0000000000", TRUE, 10},
148
149         { "MSI", N_("MSI"), gl_barcode_gnubarcode_new,
150           TRUE, TRUE, TRUE, TRUE, "0000000000", TRUE, 10},
151
152         { "PLS", N_("Plessey"), gl_barcode_gnubarcode_new,
153           TRUE, TRUE, TRUE, TRUE, "0000000000", TRUE, 10},
154
155         { "Code93", N_("Code 93"), gl_barcode_gnubarcode_new,
156           TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
157
158 #endif /* HAVE_LIBBARCODE */
159
160 #ifdef HAVE_LIBZINT
161
162         { "AUSP", N_("Australia Post Standard"), gl_barcode_zint_new,
163           TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
164
165         { "AUSRP", N_("Australia Post Reply Paid"), gl_barcode_zint_new,
166           TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
167
168         { "AUSRT", N_("Australia Post Route Code"), gl_barcode_zint_new,
169           TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
170
171         { "AUSRD", N_("Australia Post Redirect"), gl_barcode_zint_new,
172           TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
173
174         { "AZTEC", N_("Aztec Code"), gl_barcode_zint_new,
175           TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
176           
177         { "AZRUN", N_("Aztec Rune"), gl_barcode_zint_new,
178           TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
179
180         { "CBR", N_("Codabar"), gl_barcode_zint_new,
181           TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
182
183         { "Code1", N_("Code One"),  gl_barcode_zint_new,
184           TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
185
186         { "Code11", N_("Code 11"), gl_barcode_zint_new,
187           TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
188           
189         { "C16K", N_("Code 16K"), gl_barcode_zint_new,
190           TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
191           
192         { "C25M", N_("Code 2 of 5 Matrix"),  gl_barcode_zint_new,
193           TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
194           
195         { "C25I", N_("Code 2 of 5 IATA"),  gl_barcode_zint_new,
196           TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
197           
198         { "C25DL", N_("Code 2 of 5 Data Logic"),  gl_barcode_zint_new,
199           TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
200
201         { "Code32", N_("Code 32 (Italian Pharmacode)"),  gl_barcode_zint_new,
202           TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
203
204         { "Code39", N_("Code 39"), gl_barcode_zint_new,
205           TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
206           
207         { "Code39E", N_("Code 39 Extended"),  gl_barcode_zint_new,
208           TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
209
210         { "Code49", N_("Code 49"), gl_barcode_zint_new,
211           TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
212
213         { "Code93", N_("Code 93"), gl_barcode_zint_new,
214           TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
215
216         { "Code128", N_("Code 128"), gl_barcode_zint_new,
217           TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
218           
219         { "Code128B", N_("Code 128 (Mode C supression)"), gl_barcode_zint_new,
220           TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
221           
222         { "DAFT", N_("DAFT Code"), gl_barcode_zint_new,
223           TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
224
225         { "DMTX", N_("Data Matrix"), gl_barcode_zint_new,
226           TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
227
228         { "DPL", N_("Deutsche Post Leitcode"), gl_barcode_zint_new,
229           TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
230           
231         { "DPI", N_("Deutsche Post Identcode"), gl_barcode_zint_new,
232           TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
233           
234         { "KIX", N_("Dutch Post KIX Code"), gl_barcode_zint_new,
235           TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
236
237         { "EAN", N_("European Article Number (EAN)"), gl_barcode_zint_new,
238           TRUE, TRUE, TRUE, FALSE, "000000000000", FALSE, 13},
239
240         { "GMTX", N_("Grid Matrix"),  gl_barcode_zint_new,
241           TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
242
243         { "GS1-128", N_("GS1-128"), gl_barcode_zint_new,
244           TRUE, TRUE, TRUE, FALSE, "[01]00000000000000", FALSE, 18},
245
246         { "RSS14", N_("GS1 DataBar-14"), gl_barcode_zint_new,
247           TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
248           
249         { "RSSLTD", "GS1 DataBar-14 Limited",  gl_barcode_zint_new,
250           TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
251           
252         { "RSSEXP", "GS1 DataBar Extended",  gl_barcode_zint_new,
253           TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
254           
255         { "RSSS", N_("GS1 DataBar-14 Stacked"), gl_barcode_zint_new,
256           TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
257
258         { "RSSSO", N_("GS1 DataBar-14 Stacked Omni."), gl_barcode_zint_new,
259           TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
260
261         { "RSSSE", N_("GS1 DataBar Extended Stacked"), gl_barcode_zint_new,
262           TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
263
264         { "HIBC128", N_("HIBC Code 128"), gl_barcode_zint_new,
265           TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
266
267         { "HIBC39", N_("HIBC Code 39"), gl_barcode_zint_new,
268           TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
269
270         { "HIBCDM", N_("HIBC Data Matrix"), gl_barcode_zint_new,
271           TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
272
273         { "HIBCQR", N_("HIBC QR Code"), gl_barcode_zint_new,
274           TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
275
276         { "HIBCPDF", N_("HIBC PDF417"), gl_barcode_zint_new,
277           TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
278
279         { "HIBCMPDF", N_("HIBC Micro PDF417"), gl_barcode_zint_new,
280           TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
281
282         { "HIBCAZ", N_("HIBC Aztec Code"), gl_barcode_zint_new,
283           TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
284
285         { "I25", N_("Interleaved 2 of 5"), gl_barcode_zint_new,
286           TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
287
288         { "ISBN", N_("ISBN"), gl_barcode_zint_new,
289           TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
290
291         { "ITF14", N_("ITF-14"), gl_barcode_zint_new,
292           TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
293
294         { "JAPAN", N_("Japanese Postal"), gl_barcode_zint_new,
295           TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
296
297         { "KOREA", N_("Korean Postal"), gl_barcode_zint_new,
298           TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
299
300         { "LOGM", N_("LOGMARS"), gl_barcode_zint_new,
301           TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
302
303         { "MPDF", N_("Micro PDF417"), gl_barcode_zint_new,
304           TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
305
306         { "MQR", N_("Micro QR Code"), gl_barcode_zint_new,
307           TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
308
309         { "MSI", N_("MSI Plessey"), gl_barcode_zint_new,
310           TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
311
312         { "NVE", N_("NVE-18"), gl_barcode_zint_new,
313           TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
314
315         { "PDF", N_("PDF417"), gl_barcode_zint_new,
316           TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
317
318         { "PDFT", N_("PDF417 Truncated"), gl_barcode_zint_new,
319           TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
320
321         { "PLAN", N_("PLANET"), gl_barcode_zint_new,
322           TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
323
324         { "POSTNET", N_("PostNet"), gl_barcode_zint_new,
325           TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
326
327         { "PHARMA", N_("Pharmacode"), gl_barcode_zint_new,
328           TRUE, TRUE, TRUE, FALSE, "00000", TRUE, 5},
329
330         { "PHARMA2", N_("Pharmacode 2-track"), gl_barcode_zint_new,
331           TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
332
333         { "PZN", N_("Pharmazentral Nummer (PZN)"), gl_barcode_zint_new,
334           TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
335
336         { "QR", N_("QR Code"), gl_barcode_zint_new,
337           TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
338
339         { "RM4", N_("Royal Mail 4-State"), gl_barcode_zint_new,
340           TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
341
342         { "TELE", N_("Telepen"), gl_barcode_zint_new,
343           TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
344
345         { "TELEX", N_("Telepen Numeric"), gl_barcode_zint_new,
346           TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
347
348         { "UPC-A", N_("UPC-A"),  gl_barcode_zint_new,
349           TRUE, TRUE, TRUE, FALSE, "00000000000", FALSE, 11},
350           
351         { "UPC-E", N_("UPC-E"),  gl_barcode_zint_new,
352           TRUE, TRUE, TRUE, FALSE, "000000", FALSE, 6},
353           
354         { "USPS", N_("USPS One Code"), gl_barcode_zint_new,
355           TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
356
357         { "PLS", N_("UK Plessey"), gl_barcode_zint_new,
358           TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
359
360 #endif /* HAVE_LIBZINT */
361
362 #ifdef HAVE_LIBIEC16022
363
364         { "IEC16022", N_("IEC16022 (DataMatrix)"), gl_barcode_iec16022_new,
365           FALSE, FALSE, TRUE, FALSE, "12345678", TRUE, 8},
366
367 #endif /* HAVE_LIBIEC16022 */
368
369 #ifdef HAVE_LIBQRENCODE
370
371         { "IEC18004", N_("IEC18004 (QRCode)"), gl_barcode_iec18004_new,
372           FALSE, FALSE, TRUE, FALSE, "12345678", TRUE, 8},
373
374 #endif /* HAVE_LIBQRENCODE */
375
376         { NULL, NULL, NULL, FALSE, FALSE, FALSE, FALSE, NULL, FALSE, 0}
377
378 };
379
380
381 /*========================================================*/
382 /* Private function prototypes.                           */
383 /*========================================================*/
384
385 static void gl_barcode_add_shape        (glBarcode      *bc,
386                                          glBarcodeShape *shape);
387
388 static void gl_barcode_shape_free       (glBarcodeShape *shape);
389
390
391 /*---------------------------------------------------------------------------*/
392 /* Convert id to index into above table.                                     */
393 /*---------------------------------------------------------------------------*/
394 static gint
395 id_to_index (const gchar *id)
396 {
397         gint i;
398
399         if (id == 0) {
400                 return 0; /* NULL request default. I.e., the first element. */
401         }
402
403         for (i=0; backends[i].id != NULL; i++) {
404                 if (g_ascii_strcasecmp (id, backends[i].id) == 0) {
405                         return i;
406                 }
407         }
408
409         g_message( "Unknown barcode id \"%s\"", id );
410         return 0;
411 }
412
413
414 /*---------------------------------------------------------------------------*/
415 /* Convert name to index into above table.                                   */
416 /*---------------------------------------------------------------------------*/
417 static gint
418 name_to_index (const gchar *name)
419 {
420         gint i;
421
422         g_return_val_if_fail (name!=NULL, 0);
423
424         for (i=0; backends[i].id != NULL; i++) {
425                 if (strcmp (name, gettext (backends[i].name)) == 0) {
426                         return i;
427                 }
428         }
429
430         g_message( "Unknown barcode name \"%s\"", name );
431         return 0;
432 }
433
434
435 /*****************************************************************************/
436 /* Call appropriate barcode backend to create barcode in intermediate format.*/
437 /*****************************************************************************/
438 glBarcode *
439 gl_barcode_new (const gchar    *id,
440                 gboolean        text_flag,
441                 gboolean        checksum_flag,
442                 gdouble         w,
443                 gdouble         h,
444                 const gchar    *digits)
445 {
446         glBarcode *gbc;
447         gint       i;
448
449         g_return_val_if_fail (digits!=NULL, NULL);
450
451         i = id_to_index (id);
452         gbc = backends[i].new (backends[i].id,
453                                text_flag,
454                                checksum_flag,
455                                w,
456                                h,
457                                digits);
458
459         return gbc;
460 }
461
462
463 /*****************************************************************************/
464 /* Free previously created barcode.                                          */
465 /*****************************************************************************/
466 void
467 gl_barcode_free (glBarcode **gbc)
468 {
469         GList *p;
470
471         if (*gbc != NULL) {
472
473                 for (p = (*gbc)->shapes; p != NULL; p = p->next) {
474                         gl_barcode_shape_free ((glBarcodeShape *)p->data);
475                         p->data = NULL;
476                 }
477                 g_list_free ((*gbc)->shapes);
478                 (*gbc)->shapes = NULL;
479
480                 g_free (*gbc);
481                 *gbc = NULL;
482         }
483 }
484
485
486 /*****************************************************************************/
487 /* Add a line.                                                               */
488 /*****************************************************************************/
489 void
490 gl_barcode_add_line (glBarcode      *bc,
491                      gdouble         x,
492                      gdouble         y,
493                      gdouble         length,
494                      gdouble         width)
495 {
496         glBarcodeShapeLine *line_shape = g_new0 (glBarcodeShapeLine, 1);
497         line_shape->type = GL_BARCODE_SHAPE_LINE;
498
499         line_shape->x      = x;
500         line_shape->y      = y;
501         line_shape->length = length;
502         line_shape->width  = width;
503
504         gl_barcode_add_shape (bc, (glBarcodeShape *)line_shape);
505 }
506
507
508 /*****************************************************************************/
509 /* Add box.                                                                  */
510 /*****************************************************************************/
511 void
512 gl_barcode_add_box (glBarcode      *bc,
513                     gdouble         x,
514                     gdouble         y,
515                     gdouble         width,
516                     gdouble         height)
517 {
518         glBarcodeShapeBox *box_shape = g_new0 (glBarcodeShapeBox, 1);
519         box_shape->type = GL_BARCODE_SHAPE_BOX;
520
521         box_shape->x      = x;
522         box_shape->y      = y;
523         box_shape->width  = width;
524         box_shape->height = height;
525
526         gl_barcode_add_shape (bc, (glBarcodeShape *)box_shape);
527 }
528
529
530 /*****************************************************************************/
531 /* Add character.                                                            */
532 /*****************************************************************************/
533 void
534 gl_barcode_add_char (glBarcode      *bc,
535                      gdouble         x,
536                      gdouble         y,
537                      gdouble         fsize,
538                      gchar           c)
539 {
540         glBarcodeShapeChar *char_shape = g_new0 (glBarcodeShapeChar, 1);
541         char_shape->type = GL_BARCODE_SHAPE_CHAR;
542
543         char_shape->x      = x;
544         char_shape->y      = y;
545         char_shape->fsize  = fsize;
546         char_shape->c      = c;
547
548         gl_barcode_add_shape (bc, (glBarcodeShape *)char_shape);
549 }
550
551
552 /*****************************************************************************/
553 /* Add string.                                                               */
554 /*****************************************************************************/
555 void
556 gl_barcode_add_string (glBarcode      *bc,
557                        gdouble         x,
558                        gdouble         y,
559                        gdouble         fsize,
560                        gchar          *string,
561                        gsize           length)
562 {
563         glBarcodeShapeString *string_shape = g_new0 (glBarcodeShapeString, 1);
564         string_shape->type = GL_BARCODE_SHAPE_STRING;
565
566         string_shape->x      = x;
567         string_shape->y      = y;
568         string_shape->fsize  = fsize;
569         string_shape->string = g_strndup(string, length);
570
571         gl_barcode_add_shape (bc, (glBarcodeShape *)string_shape);
572 }
573
574
575 /*****************************************************************************/
576 /* Add shape to barcode.                                                     */
577 /*****************************************************************************/
578 static void
579 gl_barcode_add_shape (glBarcode      *bc,
580                       glBarcodeShape *shape)
581 {
582         g_return_if_fail (bc);
583         g_return_if_fail (shape);
584
585         bc->shapes = g_list_prepend (bc->shapes, shape);
586 }
587
588
589 /*****************************************************************************/
590 /* Free a shape primitive.                                                   */
591 /*****************************************************************************/
592 static void
593 gl_barcode_shape_free (glBarcodeShape *shape)
594 {
595         switch (shape->type)
596         {
597
598         case GL_BARCODE_SHAPE_STRING:
599                 g_free (shape->string.string);
600                 break;
601
602         default:
603                 break;
604         }
605
606         g_free (shape);
607 }
608
609
610 /*****************************************************************************/
611 /* Get a list of names for valid barcode styles.                             */
612 /*****************************************************************************/
613 GList *
614 gl_barcode_get_styles_list  (void)
615 {
616         gint   i;
617         GList *list = NULL;
618
619         for (i=0; backends[i].id != NULL; i++) {
620                 list = g_list_prepend (list, g_strdup (gettext (backends[i].name)));
621         }
622
623         return g_list_reverse (list);
624 }
625
626
627 /*****************************************************************************/
628 /* Free up a previously allocated list of style names.                       */
629 /*****************************************************************************/
630 void
631 gl_barcode_free_styles_list (GList *styles_list)
632 {
633         GList *p;
634
635         for (p=styles_list; p != NULL; p=p->next) {
636                 g_free (p->data);
637                 p->data = NULL;
638         }
639
640         g_list_free (styles_list);
641 }
642
643
644 /*****************************************************************************/
645 /* Return an appropriate set of digits for the given barcode style.          */
646 /*****************************************************************************/
647 gchar *
648 gl_barcode_default_digits (const gchar *id,
649                            guint        n)
650 {
651         int i;
652
653         i = id_to_index (id);
654
655         if (backends[i].can_freeform) {
656
657                 return g_strnfill (MAX (n,1), '0');
658
659         } else {
660
661                 return g_strdup (backends[i].default_digits);
662
663         }
664 }
665
666
667 /*****************************************************************************/
668 /* Query text capabilities.                                                  */
669 /*****************************************************************************/
670 gboolean
671 gl_barcode_can_text (const gchar *id)
672 {
673         return backends[id_to_index (id)].can_text;
674 }
675
676
677 gboolean
678 gl_barcode_text_optional (const gchar *id)
679 {
680         return backends[id_to_index (id)].text_optional;
681 }
682
683
684 /*****************************************************************************/
685 /* Query checksum capabilities.                                              */
686 /*****************************************************************************/
687 gboolean
688 gl_barcode_can_csum (const gchar *id)
689 {
690         return backends[id_to_index (id)].can_checksum;
691 }
692
693
694 gboolean
695 gl_barcode_csum_optional (const gchar *id)
696 {
697         return backends[id_to_index (id)].checksum_optional;
698 }
699
700
701 /*****************************************************************************/
702 /* Query if freeform input is allowed.                                       */
703 /*****************************************************************************/
704 gboolean
705 gl_barcode_can_freeform     (const gchar    *id)
706 {
707         return backends[id_to_index (id)].can_freeform;
708 }
709
710
711 /*****************************************************************************/
712 /* Query prefered number of digits of input.                                 */
713 /*****************************************************************************/
714 guint
715 gl_barcode_get_prefered_n (const gchar    *id)
716 {
717         return backends[id_to_index (id)].prefered_n;
718 }
719
720
721 /*****************************************************************************/
722 /* Convert style to text.                                                    */
723 /*****************************************************************************/
724 const gchar *
725 gl_barcode_id_to_name (const gchar *id)
726 {
727         return gettext (backends[id_to_index (id)].name);
728 }
729
730
731 /*****************************************************************************/
732 /* Convert name to style.                                                    */
733 /*****************************************************************************/
734 const gchar *
735 gl_barcode_name_to_id (const gchar *name)
736 {
737         g_return_val_if_fail (name!=NULL, backends[0].id);
738
739         return backends[name_to_index (name)].id;
740 }
741
742
743
744 /*
745  * Local Variables:       -- emacs
746  * mode: C                -- emacs
747  * c-basic-offset: 8      -- emacs
748  * tab-width: 8           -- emacs
749  * indent-tabs-mode: nil  -- emacs
750  * End:                   -- emacs
751  */