[glabels/zint] More refactoring of barcode subsystem.



commit b5865243f8cb28214bfed442ee5d7cbee2967bc2
Author: Jim Evins <evins snaught com>
Date:   Sun Jul 11 14:00:20 2010 -0400

    More refactoring of barcode subsystem.
    
    Create a clear separation between the intermediate barcode format and
    the management of the barcode backends.

 src/Makefile.am             |    4 +
 src/bc-backends.c           |  609 +++++++++++++++++++++++++++++++++++++++++++
 src/bc-backends.h           |   71 +++++
 src/bc-gnubarcode.c         |    2 +-
 src/bc-iec16022.c           |    2 +-
 src/bc-iec18004.c           |    2 +-
 src/bc-postnet.c            |    2 +-
 src/bc-zint.c               |    2 +-
 src/bc.c                    |  557 ++--------------------------------------
 src/bc.h                    |  115 +++-----
 src/label-barcode.c         |   35 ++--
 src/label-barcode.h         |    1 -
 src/object-editor-bc-page.c |   39 ++--
 src/object-editor.h         |    1 -
 14 files changed, 789 insertions(+), 653 deletions(-)
---
diff --git a/src/Makefile.am b/src/Makefile.am
index 4ebd3a1..57d4750 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -121,6 +121,8 @@ glabels_3_SOURCES = 			\
 	template-designer.h		\
 	bc.c				\
 	bc.h				\
+	bc-backends.c			\
+	bc-backends.h			\
 	bc-gnubarcode.c			\
 	bc-gnubarcode.h			\
 	bc-zint.c			\
@@ -248,6 +250,8 @@ glabels_3_batch_SOURCES = 		\
 	print-op.h			\
 	bc.c				\
 	bc.h				\
+	bc-backends.c			\
+	bc-backends.h			\
 	bc-gnubarcode.c			\
 	bc-gnubarcode.h			\
 	bc-zint.c			\
diff --git a/src/bc-backends.c b/src/bc-backends.c
new file mode 100644
index 0000000..5c0e913
--- /dev/null
+++ b/src/bc-backends.c
@@ -0,0 +1,609 @@
+/*
+ *  bc-backends.c
+ *  Copyright (C) 2001-2009  Jim Evins <evins snaught com>.
+ *
+ *  This file is part of gLabels.
+ *
+ *  gLabels is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  gLabels is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with gLabels.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+
+#include "bc-backends.h"
+
+#include <glib.h>
+#include <glib/gi18n.h>
+
+#include "bc-postnet.h"
+#include "bc-gnubarcode.h"
+#include "bc-zint.h"
+#include "bc-iec16022.h"
+#include "bc-iec18004.h"
+
+#include "debug.h"
+
+
+/*========================================================*/
+/* Private macros and constants.                          */
+/*========================================================*/
+
+
+/*========================================================*/
+/* Private types.                                         */
+/*========================================================*/
+
+typedef glBarcode *(*glBarcodeNewFunc) (const gchar    *id,
+                                        gboolean        text_flag,
+                                        gboolean        checksum_flag,
+                                        gdouble         w,
+                                        gdouble         h,
+                                        const gchar    *digits);
+
+
+typedef struct {
+        gchar            *id;
+        gchar            *name;
+        glBarcodeNewFunc  new_barcode;
+        gboolean          can_text;
+        gboolean          text_optional;
+        gboolean          can_checksum;
+        gboolean          checksum_optional;
+        gchar            *default_digits;
+        gboolean          can_freeform;
+        guint             prefered_n;
+} Backend;
+
+
+/*========================================================*/
+/* Private globals.                                       */
+/*========================================================*/
+
+static const Backend backends[] = {
+
+        { "POSTNET", N_("POSTNET (any)"), gl_barcode_postnet_new,
+          FALSE, FALSE, TRUE, FALSE, "12345-6789-12", FALSE, 11},
+
+        { "POSTNET-5", N_("POSTNET-5 (ZIP only)"), gl_barcode_postnet_new,
+          FALSE, FALSE, TRUE, FALSE, "12345", FALSE, 5},
+
+        { "POSTNET-9", N_("POSTNET-9 (ZIP+4)"), gl_barcode_postnet_new,
+          FALSE, FALSE, TRUE, FALSE, "12345-6789", FALSE, 9},
+
+        { "POSTNET-11", N_("POSTNET-11 (DPBC)"), gl_barcode_postnet_new,
+          FALSE, FALSE, TRUE, FALSE, "12345-6789-12", FALSE, 11},
+
+        { "CEPNET", N_("CEPNET"), gl_barcode_postnet_new,
+          FALSE, FALSE, TRUE, FALSE, "12345-678", FALSE, 8},
+
+#ifdef HAVE_LIBBARCODE
+
+        { "EAN", N_("EAN (any)"), gl_barcode_gnubarcode_new,
+          TRUE, TRUE, TRUE, FALSE, "000000000000 00000", FALSE, 17},
+
+        { "EAN-8", N_("EAN-8"), gl_barcode_gnubarcode_new,
+          TRUE, TRUE, TRUE, FALSE, "0000000", FALSE, 7},
+
+        { "EAN-8+2", N_("EAN-8 +2"), gl_barcode_gnubarcode_new,
+          TRUE, TRUE, TRUE, FALSE, "0000000 00", FALSE, 9},
+
+        { "EAN-8+5", N_("EAN-8 +5"), gl_barcode_gnubarcode_new,
+          TRUE, TRUE, TRUE, FALSE, "0000000 00000", FALSE, 12},
+
+        { "EAN-13", N_("EAN-13"), gl_barcode_gnubarcode_new,
+          TRUE, TRUE, TRUE, FALSE, "000000000000", FALSE, 12},
+
+        { "EAN-13+2", N_("EAN-13 +2"), gl_barcode_gnubarcode_new,
+          TRUE, TRUE, TRUE, FALSE, "000000000000 00", FALSE, 14},
+
+        { "EAN-13+5", N_("EAN-13 +5"), gl_barcode_gnubarcode_new,
+          TRUE, TRUE, TRUE, FALSE, "000000000000 00000", FALSE, 17},
+
+        { "UPC", N_("UPC (UPC-A or UPC-E)"), gl_barcode_gnubarcode_new,
+          TRUE, TRUE, TRUE, FALSE, "00000000000 00000", FALSE, 16},
+
+        { "UPC-A", N_("UPC-A"), gl_barcode_gnubarcode_new,
+          TRUE, TRUE, TRUE, FALSE, "00000000000", FALSE, 11},
+
+        { "UPC-A+2", N_("UPC-A +2"), gl_barcode_gnubarcode_new,
+          TRUE, TRUE, TRUE, FALSE, "00000000000 00", FALSE, 13},
+
+        { "UPC-A+5", N_("UPC-A +5"), gl_barcode_gnubarcode_new,
+          TRUE, TRUE, TRUE, FALSE, "00000000000 00000", FALSE, 16},
+
+        { "UPC-E", N_("UPC-E"), gl_barcode_gnubarcode_new,
+          TRUE, TRUE, TRUE, FALSE, "000000", FALSE, 6},
+
+        { "UPC-E+2", N_("UPC-E +2"), gl_barcode_gnubarcode_new,
+          TRUE, TRUE, TRUE, FALSE, "000000 00", FALSE, 8},
+
+        { "UPC-E+5", N_("UPC-E +5"), gl_barcode_gnubarcode_new,
+          TRUE, TRUE, TRUE, FALSE, "000000 00000", FALSE, 11},
+
+        { "ISBN", N_("ISBN"), gl_barcode_gnubarcode_new,
+          TRUE, TRUE, TRUE, TRUE, "0-00000-000-0", FALSE, 10},
+
+        { "ISBN+5", N_("ISBN +5"), gl_barcode_gnubarcode_new,
+          TRUE, TRUE, TRUE, TRUE, "0-00000-000-0 00000", FALSE, 15},
+
+        { "Code39", N_("Code 39"), gl_barcode_gnubarcode_new,
+          TRUE, TRUE, TRUE, TRUE, "0000000000", TRUE, 10},
+
+        { "Code128", N_("Code 128"), gl_barcode_gnubarcode_new,
+          TRUE, TRUE, TRUE, TRUE, "0000000000", TRUE, 10},
+
+        { "Code128C", N_("Code 128C"), gl_barcode_gnubarcode_new,
+          TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
+
+        { "Code128B", N_("Code 128B"), gl_barcode_gnubarcode_new,
+          TRUE, TRUE, TRUE, TRUE, "0000000000", TRUE, 10},
+
+        { "I25", N_("Interleaved 2 of 5"), gl_barcode_gnubarcode_new,
+          TRUE, TRUE, TRUE, TRUE, "0000000000", TRUE, 10},
+
+        { "CBR", N_("Codabar"), gl_barcode_gnubarcode_new,
+          TRUE, TRUE, TRUE, TRUE, "0000000000", TRUE, 10},
+
+        { "MSI", N_("MSI"), gl_barcode_gnubarcode_new,
+          TRUE, TRUE, TRUE, TRUE, "0000000000", TRUE, 10},
+
+        { "PLS", N_("Plessey"), gl_barcode_gnubarcode_new,
+          TRUE, TRUE, TRUE, TRUE, "0000000000", TRUE, 10},
+
+        { "Code93", N_("Code 93"), gl_barcode_gnubarcode_new,
+          TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
+
+#endif /* HAVE_LIBBARCODE */
+
+#ifdef HAVE_LIBZINT
+
+        { "AUSP", N_("Australia Post Standard"), gl_barcode_zint_new,
+          TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
+
+        { "AUSRP", N_("Australia Post Reply Paid"), gl_barcode_zint_new,
+          TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
+
+        { "AUSRT", N_("Australia Post Route Code"), gl_barcode_zint_new,
+          TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
+
+        { "AUSRD", N_("Australia Post Redirect"), gl_barcode_zint_new,
+          TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
+
+        { "AZTEC", N_("Aztec Code"), gl_barcode_zint_new,
+          TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
+          
+        { "AZRUN", N_("Aztec Rune"), gl_barcode_zint_new,
+          TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
+
+        { "CBR", N_("Codabar"), gl_barcode_zint_new,
+          TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
+
+        { "Code1", N_("Code One"),  gl_barcode_zint_new,
+          TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
+
+        { "Code11", N_("Code 11"), gl_barcode_zint_new,
+          TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
+          
+        { "C16K", N_("Code 16K"), gl_barcode_zint_new,
+          TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
+          
+        { "C25M", N_("Code 2 of 5 Matrix"),  gl_barcode_zint_new,
+          TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
+          
+        { "C25I", N_("Code 2 of 5 IATA"),  gl_barcode_zint_new,
+          TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
+          
+        { "C25DL", N_("Code 2 of 5 Data Logic"),  gl_barcode_zint_new,
+          TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
+
+        { "Code32", N_("Code 32 (Italian Pharmacode)"),  gl_barcode_zint_new,
+          TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
+
+        { "Code39", N_("Code 39"), gl_barcode_zint_new,
+          TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
+          
+        { "Code39E", N_("Code 39 Extended"),  gl_barcode_zint_new,
+          TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
+
+        { "Code49", N_("Code 49"), gl_barcode_zint_new,
+          TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
+
+        { "Code93", N_("Code 93"), gl_barcode_zint_new,
+          TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
+
+        { "Code128", N_("Code 128"), gl_barcode_zint_new,
+          TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
+          
+        { "Code128B", N_("Code 128 (Mode C supression)"), gl_barcode_zint_new,
+          TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
+          
+        { "DAFT", N_("DAFT Code"), gl_barcode_zint_new,
+          TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
+
+        { "DMTX", N_("Data Matrix"), gl_barcode_zint_new,
+          TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
+
+        { "DPL", N_("Deutsche Post Leitcode"), gl_barcode_zint_new,
+          TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
+          
+        { "DPI", N_("Deutsche Post Identcode"), gl_barcode_zint_new,
+          TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
+          
+        { "KIX", N_("Dutch Post KIX Code"), gl_barcode_zint_new,
+          TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
+
+        { "EAN", N_("European Article Number (EAN)"), gl_barcode_zint_new,
+          TRUE, TRUE, TRUE, FALSE, "000000000000", FALSE, 13},
+
+        { "GMTX", N_("Grid Matrix"),  gl_barcode_zint_new,
+          TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
+
+        { "GS1-128", N_("GS1-128"), gl_barcode_zint_new,
+          TRUE, TRUE, TRUE, FALSE, "[01]00000000000000", FALSE, 18},
+
+        { "RSS14", N_("GS1 DataBar-14"), gl_barcode_zint_new,
+          TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
+          
+        { "RSSLTD", "GS1 DataBar-14 Limited",  gl_barcode_zint_new,
+          TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
+          
+        { "RSSEXP", "GS1 DataBar Extended",  gl_barcode_zint_new,
+          TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
+          
+        { "RSSS", N_("GS1 DataBar-14 Stacked"), gl_barcode_zint_new,
+          TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
+
+        { "RSSSO", N_("GS1 DataBar-14 Stacked Omni."), gl_barcode_zint_new,
+          TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
+
+        { "RSSSE", N_("GS1 DataBar Extended Stacked"), gl_barcode_zint_new,
+          TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
+
+        { "HIBC128", N_("HIBC Code 128"), gl_barcode_zint_new,
+          TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
+
+        { "HIBC39", N_("HIBC Code 39"), gl_barcode_zint_new,
+          TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
+
+        { "HIBCDM", N_("HIBC Data Matrix"), gl_barcode_zint_new,
+          TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
+
+        { "HIBCQR", N_("HIBC QR Code"), gl_barcode_zint_new,
+          TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
+
+        { "HIBCPDF", N_("HIBC PDF417"), gl_barcode_zint_new,
+          TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
+
+        { "HIBCMPDF", N_("HIBC Micro PDF417"), gl_barcode_zint_new,
+          TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
+
+        { "HIBCAZ", N_("HIBC Aztec Code"), gl_barcode_zint_new,
+          TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
+
+        { "I25", N_("Interleaved 2 of 5"), gl_barcode_zint_new,
+          TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
+
+        { "ISBN", N_("ISBN"), gl_barcode_zint_new,
+          TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
+
+        { "ITF14", N_("ITF-14"), gl_barcode_zint_new,
+          TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
+
+        { "JAPAN", N_("Japanese Postal"), gl_barcode_zint_new,
+          TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
+
+        { "KOREA", N_("Korean Postal"), gl_barcode_zint_new,
+          TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
+
+        { "LOGM", N_("LOGMARS"), gl_barcode_zint_new,
+          TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
+
+        { "MPDF", N_("Micro PDF417"), gl_barcode_zint_new,
+          TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
+
+        { "MQR", N_("Micro QR Code"), gl_barcode_zint_new,
+          TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
+
+        { "MSI", N_("MSI Plessey"), gl_barcode_zint_new,
+          TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
+
+        { "NVE", N_("NVE-18"), gl_barcode_zint_new,
+          TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
+
+        { "PDF", N_("PDF417"), gl_barcode_zint_new,
+          TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
+
+        { "PDFT", N_("PDF417 Truncated"), gl_barcode_zint_new,
+          TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
+
+        { "PLAN", N_("PLANET"), gl_barcode_zint_new,
+          TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
+
+        { "POSTNET", N_("PostNet"), gl_barcode_zint_new,
+          TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
+
+        { "PHARMA", N_("Pharmacode"), gl_barcode_zint_new,
+          TRUE, TRUE, TRUE, FALSE, "00000", TRUE, 5},
+
+        { "PHARMA2", N_("Pharmacode 2-track"), gl_barcode_zint_new,
+          TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
+
+        { "PZN", N_("Pharmazentral Nummer (PZN)"), gl_barcode_zint_new,
+          TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
+
+        { "QR", N_("QR Code"), gl_barcode_zint_new,
+          TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
+
+        { "RM4", N_("Royal Mail 4-State"), gl_barcode_zint_new,
+          TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
+
+        { "TELE", N_("Telepen"), gl_barcode_zint_new,
+          TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
+
+        { "TELEX", N_("Telepen Numeric"), gl_barcode_zint_new,
+          TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
+
+        { "UPC-A", N_("UPC-A"),  gl_barcode_zint_new,
+          TRUE, TRUE, TRUE, FALSE, "00000000000", FALSE, 11},
+          
+        { "UPC-E", N_("UPC-E"),  gl_barcode_zint_new,
+          TRUE, TRUE, TRUE, FALSE, "000000", FALSE, 6},
+          
+        { "USPS", N_("USPS One Code"), gl_barcode_zint_new,
+          TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
+
+        { "PLS", N_("UK Plessey"), gl_barcode_zint_new,
+          TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
+
+#endif /* HAVE_LIBZINT */
+
+#ifdef HAVE_LIBIEC16022
+
+        { "IEC16022", N_("IEC16022 (DataMatrix)"), gl_barcode_iec16022_new,
+          FALSE, FALSE, TRUE, FALSE, "12345678", TRUE, 8},
+
+#endif /* HAVE_LIBIEC16022 */
+
+#ifdef HAVE_LIBQRENCODE
+
+        { "IEC18004", N_("IEC18004 (QRCode)"), gl_barcode_iec18004_new,
+          FALSE, FALSE, TRUE, FALSE, "12345678", TRUE, 8},
+
+#endif /* HAVE_LIBQRENCODE */
+
+        { NULL, NULL, NULL, FALSE, FALSE, FALSE, FALSE, NULL, FALSE, 0}
+
+};
+
+
+/*========================================================*/
+/* Private function prototypes.                           */
+/*========================================================*/
+
+static gint id_to_index   (const gchar *id);
+static gint name_to_index (const gchar *name);
+
+/*---------------------------------------------------------------------------*/
+/* Convert id to index into above table.                                     */
+/*---------------------------------------------------------------------------*/
+static gint
+id_to_index (const gchar *id)
+{
+        gint i;
+
+        if (id == 0) {
+                return 0; /* NULL request default. I.e., the first element. */
+        }
+
+        for (i=0; backends[i].id != NULL; i++) {
+                if (g_ascii_strcasecmp (id, backends[i].id) == 0) {
+                        return i;
+                }
+        }
+
+        g_message( "Unknown barcode id \"%s\"", id );
+        return 0;
+}
+
+
+/*---------------------------------------------------------------------------*/
+/* Convert name to index into above table.                                   */
+/*---------------------------------------------------------------------------*/
+static gint
+name_to_index (const gchar *name)
+{
+        gint i;
+
+        g_return_val_if_fail (name!=NULL, 0);
+
+        for (i=0; backends[i].id != NULL; i++) {
+                if (strcmp (name, gettext (backends[i].name)) == 0) {
+                        return i;
+                }
+        }
+
+        g_message( "Unknown barcode name \"%s\"", name );
+        return 0;
+}
+
+
+/*****************************************************************************/
+/* Get a list of names for valid barcode styles.                             */
+/*****************************************************************************/
+GList *
+gl_barcode_backends_get_styles_list  (void)
+{
+        gint   i;
+        GList *list = NULL;
+
+        for (i=0; backends[i].id != NULL; i++) {
+                list = g_list_prepend (list, g_strdup (gettext (backends[i].name)));
+        }
+
+        return g_list_reverse (list);
+}
+
+
+/*****************************************************************************/
+/* Free up a previously allocated list of style names.                       */
+/*****************************************************************************/
+void
+gl_barcode_backends_free_styles_list (GList *styles_list)
+{
+        GList *p;
+
+        for (p=styles_list; p != NULL; p=p->next) {
+                g_free (p->data);
+                p->data = NULL;
+        }
+
+        g_list_free (styles_list);
+}
+
+
+/*****************************************************************************/
+/* Return an appropriate set of digits for the given barcode style.          */
+/*****************************************************************************/
+gchar *
+gl_barcode_backends_default_digits (const gchar *id,
+                           guint        n)
+{
+        int i;
+
+        i = id_to_index (id);
+
+        if (backends[i].can_freeform) {
+
+                return g_strnfill (MAX (n,1), '0');
+
+        } else {
+
+                return g_strdup (backends[i].default_digits);
+
+        }
+}
+
+
+/*****************************************************************************/
+/* Query text capabilities.                                                  */
+/*****************************************************************************/
+gboolean
+gl_barcode_backends_can_text (const gchar *id)
+{
+        return backends[id_to_index (id)].can_text;
+}
+
+
+gboolean
+gl_barcode_backends_text_optional (const gchar *id)
+{
+        return backends[id_to_index (id)].text_optional;
+}
+
+
+/*****************************************************************************/
+/* Query checksum capabilities.                                              */
+/*****************************************************************************/
+gboolean
+gl_barcode_backends_can_csum (const gchar *id)
+{
+        return backends[id_to_index (id)].can_checksum;
+}
+
+
+gboolean
+gl_barcode_backends_csum_optional (const gchar *id)
+{
+        return backends[id_to_index (id)].checksum_optional;
+}
+
+
+/*****************************************************************************/
+/* Query if freeform input is allowed.                                       */
+/*****************************************************************************/
+gboolean
+gl_barcode_backends_can_freeform     (const gchar    *id)
+{
+        return backends[id_to_index (id)].can_freeform;
+}
+
+
+/*****************************************************************************/
+/* Query prefered number of digits of input.                                 */
+/*****************************************************************************/
+guint
+gl_barcode_backends_get_prefered_n (const gchar    *id)
+{
+        return backends[id_to_index (id)].prefered_n;
+}
+
+
+/*****************************************************************************/
+/* Convert style to text.                                                    */
+/*****************************************************************************/
+const gchar *
+gl_barcode_backends_id_to_name (const gchar *id)
+{
+        return gettext (backends[id_to_index (id)].name);
+}
+
+
+/*****************************************************************************/
+/* Convert name to style.                                                    */
+/*****************************************************************************/
+const gchar *
+gl_barcode_backends_name_to_id (const gchar *name)
+{
+        g_return_val_if_fail (name!=NULL, backends[0].id);
+
+        return backends[name_to_index (name)].id;
+}
+
+
+/*****************************************************************************/
+/* Call appropriate barcode backend to create barcode in intermediate format.*/
+/*****************************************************************************/
+glBarcode *
+gl_barcode_backends_new_barcode (const gchar    *id,
+                                 gboolean        text_flag,
+                                 gboolean        checksum_flag,
+                                 gdouble         w,
+                                 gdouble         h,
+                                 const gchar    *digits)
+{
+        glBarcode *gbc;
+        gint       i;
+
+        g_return_val_if_fail (digits!=NULL, NULL);
+
+        i = id_to_index (id);
+        gbc = backends[i].new_barcode (backends[i].id,
+                                       text_flag,
+                                       checksum_flag,
+                                       w,
+                                       h,
+                                       digits);
+
+        return gbc;
+}
+
+
+
+/*
+ * Local Variables:       -- emacs
+ * mode: C                -- emacs
+ * c-basic-offset: 8      -- emacs
+ * tab-width: 8           -- emacs
+ * indent-tabs-mode: nil  -- emacs
+ * End:                   -- emacs
+ */
diff --git a/src/bc-backends.h b/src/bc-backends.h
new file mode 100644
index 0000000..6d95580
--- /dev/null
+++ b/src/bc-backends.h
@@ -0,0 +1,71 @@
+/*
+ *  bc-backends.h
+ *  Copyright (C) 2001-2010  Jim Evins <evins snaught com>.
+ *
+ *  This file is part of gLabels.
+ *
+ *  gLabels is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  gLabels is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with gLabels.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __BC_BACKENDS_H__
+#define __BC_BACKENDS_H__
+
+#include <glib.h>
+#include "bc.h"
+
+G_BEGIN_DECLS
+
+
+GList           *gl_barcode_backends_get_styles_list  (void);
+void             gl_barcode_backends_free_styles_list (GList          *styles_list);
+
+gchar           *gl_barcode_backends_default_digits   (const gchar    *id,
+                                                       guint           n);
+
+gboolean         gl_barcode_backends_can_text         (const gchar    *id);
+gboolean         gl_barcode_backends_text_optional    (const gchar    *id);
+
+gboolean         gl_barcode_backends_can_csum         (const gchar    *id);
+gboolean         gl_barcode_backends_csum_optional    (const gchar    *id);
+
+gboolean         gl_barcode_backends_can_freeform     (const gchar    *id);
+guint            gl_barcode_backends_get_prefered_n   (const gchar    *id);
+
+const gchar     *gl_barcode_backends_id_to_name       (const gchar    *id);
+const gchar     *gl_barcode_backends_name_to_id       (const gchar    *name);
+
+glBarcode       *gl_barcode_backends_new_barcode      (const gchar    *id,
+                                                       gboolean        text_flag,
+                                                       gboolean        checksum_flag,
+                                                       gdouble         w,
+                                                       gdouble         h,
+                                                       const gchar    *digits);
+
+
+
+
+G_END_DECLS
+
+#endif /* __BC_BACKENDS_H__ */
+
+
+
+/*
+ * Local Variables:       -- emacs
+ * mode: C                -- emacs
+ * c-basic-offset: 8      -- emacs
+ * tab-width: 8           -- emacs
+ * indent-tabs-mode: nil  -- emacs
+ * End:                   -- emacs
+ */
diff --git a/src/bc-gnubarcode.c b/src/bc-gnubarcode.c
index d8d096d..327b02f 100644
--- a/src/bc-gnubarcode.c
+++ b/src/bc-gnubarcode.c
@@ -282,7 +282,7 @@ render_pass1 (struct Barcode_Item *bci,
 		bci->height = i * scalef;
 	}
 
-	gbc = g_new0 (glBarcode, 1);
+	gbc = gl_barcode_new ();
 
 	/* Now traverse the code string and create a list of lines */
 	x = bci->margin + (bci->partial[0] - '0') * scalef;
diff --git a/src/bc-iec16022.c b/src/bc-iec16022.c
index e56990d..dbd06ec 100644
--- a/src/bc-iec16022.c
+++ b/src/bc-iec16022.c
@@ -115,7 +115,7 @@ render_iec16022 (const gchar *grid,
                 pixel_size = MIN_PIXEL_SIZE;
         }
 
-        gbc = g_new0 (glBarcode, 1);
+        gbc = gl_barcode_new ();
 
         /* Now traverse the code string and create a list of boxes */
         for ( y = i_height-1; y >= 0; y-- )
diff --git a/src/bc-iec18004.c b/src/bc-iec18004.c
index 33f2789..0237352 100644
--- a/src/bc-iec18004.c
+++ b/src/bc-iec18004.c
@@ -120,7 +120,7 @@ render_iec18004 (const gchar *grid,
                 pixel_size = MIN_PIXEL_SIZE;
         }
 
-        gbc = g_new0 (glBarcode, 1);
+        gbc = gl_barcode_new ();
 
         /* Now traverse the code string and create a list of boxes */
         for ( y = 0; y < i_height; y++ )
diff --git a/src/bc-postnet.c b/src/bc-postnet.c
index 3aa1765..5ed6b87 100644
--- a/src/bc-postnet.c
+++ b/src/bc-postnet.c
@@ -122,7 +122,7 @@ gl_barcode_postnet_new (const gchar    *id,
 		return NULL;
 	}
 
-	gbc = g_new0 (glBarcode, 1);
+	gbc = gl_barcode_new ();
 
 	/* Now traverse the code string and create a list of lines */
 	x = POSTNET_HORIZ_MARGIN;
diff --git a/src/bc-zint.c b/src/bc-zint.c
index c8d6d07..d8f3ebd 100644
--- a/src/bc-zint.c
+++ b/src/bc-zint.c
@@ -188,7 +188,7 @@ static glBarcode *render_zint(struct zint_symbol *symbol, gboolean text_flag)
 
 
         render = symbol->rendered;
-        gbc = g_new0(glBarcode, 1);
+        gbc = gl_barcode_new ();
 	
         for ( zline = render->lines; zline != NULL; zline = zline->next )
         {
diff --git a/src/bc.c b/src/bc.c
index ca3d42f..aa5529c 100644
--- a/src/bc.c
+++ b/src/bc.c
@@ -43,340 +43,11 @@
 /* Private types.                                         */
 /*========================================================*/
 
-typedef struct {
-	gchar            *id;
-	gchar            *name;
-	glBarcodeNewFunc  new;
-	gboolean          can_text;
-	gboolean          text_optional;
-	gboolean          can_checksum;
-	gboolean          checksum_optional;
-	gchar            *default_digits;
-	gboolean          can_freeform;
-	guint             prefered_n;
-} Backend;
-
 
 /*========================================================*/
 /* Private globals.                                       */
 /*========================================================*/
 
-static const Backend backends[] = {
-
-	{ "POSTNET", N_("POSTNET (any)"), gl_barcode_postnet_new,
-	  FALSE, FALSE, TRUE, FALSE, "12345-6789-12", FALSE, 11},
-
-	{ "POSTNET-5", N_("POSTNET-5 (ZIP only)"), gl_barcode_postnet_new,
-	  FALSE, FALSE, TRUE, FALSE, "12345", FALSE, 5},
-
-	{ "POSTNET-9", N_("POSTNET-9 (ZIP+4)"), gl_barcode_postnet_new,
-	  FALSE, FALSE, TRUE, FALSE, "12345-6789", FALSE, 9},
-
-	{ "POSTNET-11", N_("POSTNET-11 (DPBC)"), gl_barcode_postnet_new,
-	  FALSE, FALSE, TRUE, FALSE, "12345-6789-12", FALSE, 11},
-
-#ifdef HAVE_LIBBARCODE
-
-	{ "CEPNET", N_("CEPNET"), gl_barcode_postnet_new,
-	  FALSE, FALSE, TRUE, FALSE, "12345-678", FALSE, 8},
-
-	{ "EAN", N_("EAN (any)"), gl_barcode_gnubarcode_new,
-	  TRUE, TRUE, TRUE, FALSE, "000000000000 00000", FALSE, 17},
-
-	{ "EAN-8", N_("EAN-8"), gl_barcode_gnubarcode_new,
-	  TRUE, TRUE, TRUE, FALSE, "0000000", FALSE, 7},
-
-	{ "EAN-8+2", N_("EAN-8 +2"), gl_barcode_gnubarcode_new,
-	  TRUE, TRUE, TRUE, FALSE, "0000000 00", FALSE, 9},
-
-	{ "EAN-8+5", N_("EAN-8 +5"), gl_barcode_gnubarcode_new,
-	  TRUE, TRUE, TRUE, FALSE, "0000000 00000", FALSE, 12},
-
-	{ "EAN-13", N_("EAN-13"), gl_barcode_gnubarcode_new,
-	  TRUE, TRUE, TRUE, FALSE, "000000000000", FALSE, 12},
-
-	{ "EAN-13+2", N_("EAN-13 +2"), gl_barcode_gnubarcode_new,
-	  TRUE, TRUE, TRUE, FALSE, "000000000000 00", FALSE, 14},
-
-	{ "EAN-13+5", N_("EAN-13 +5"), gl_barcode_gnubarcode_new,
-	  TRUE, TRUE, TRUE, FALSE, "000000000000 00000", FALSE, 17},
-
-	{ "UPC", N_("UPC (UPC-A or UPC-E)"), gl_barcode_gnubarcode_new,
-	  TRUE, TRUE, TRUE, FALSE, "00000000000 00000", FALSE, 16},
-
-	{ "UPC-A", N_("UPC-A"), gl_barcode_gnubarcode_new,
-	  TRUE, TRUE, TRUE, FALSE, "00000000000", FALSE, 11},
-
-	{ "UPC-A+2", N_("UPC-A +2"), gl_barcode_gnubarcode_new,
-	  TRUE, TRUE, TRUE, FALSE, "00000000000 00", FALSE, 13},
-
-	{ "UPC-A+5", N_("UPC-A +5"), gl_barcode_gnubarcode_new,
-	  TRUE, TRUE, TRUE, FALSE, "00000000000 00000", FALSE, 16},
-
-	{ "UPC-E", N_("UPC-E"), gl_barcode_gnubarcode_new,
-	  TRUE, TRUE, TRUE, FALSE, "000000", FALSE, 6},
-
-	{ "UPC-E+2", N_("UPC-E +2"), gl_barcode_gnubarcode_new,
-	  TRUE, TRUE, TRUE, FALSE, "000000 00", FALSE, 8},
-
-	{ "UPC-E+5", N_("UPC-E +5"), gl_barcode_gnubarcode_new,
-	  TRUE, TRUE, TRUE, FALSE, "000000 00000", FALSE, 11},
-
-	{ "ISBN", N_("ISBN"), gl_barcode_gnubarcode_new,
-	  TRUE, TRUE, TRUE, TRUE, "0-00000-000-0", FALSE, 10},
-
-	{ "ISBN+5", N_("ISBN +5"), gl_barcode_gnubarcode_new,
-	  TRUE, TRUE, TRUE, TRUE, "0-00000-000-0 00000", FALSE, 15},
-
-	{ "Code39", N_("Code 39"), gl_barcode_gnubarcode_new,
-	  TRUE, TRUE, TRUE, TRUE, "0000000000", TRUE, 10},
-
-	{ "Code128", N_("Code 128"), gl_barcode_gnubarcode_new,
-	  TRUE, TRUE, TRUE, TRUE, "0000000000", TRUE, 10},
-
-	{ "Code128C", N_("Code 128C"), gl_barcode_gnubarcode_new,
-	  TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
-
-	{ "Code128B", N_("Code 128B"), gl_barcode_gnubarcode_new,
-	  TRUE, TRUE, TRUE, TRUE, "0000000000", TRUE, 10},
-
-	{ "I25", N_("Interleaved 2 of 5"), gl_barcode_gnubarcode_new,
-	  TRUE, TRUE, TRUE, TRUE, "0000000000", TRUE, 10},
-
-	{ "CBR", N_("Codabar"), gl_barcode_gnubarcode_new,
-	  TRUE, TRUE, TRUE, TRUE, "0000000000", TRUE, 10},
-
-	{ "MSI", N_("MSI"), gl_barcode_gnubarcode_new,
-	  TRUE, TRUE, TRUE, TRUE, "0000000000", TRUE, 10},
-
-	{ "PLS", N_("Plessey"), gl_barcode_gnubarcode_new,
-	  TRUE, TRUE, TRUE, TRUE, "0000000000", TRUE, 10},
-
-	{ "Code93", N_("Code 93"), gl_barcode_gnubarcode_new,
-	  TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
-
-#endif /* HAVE_LIBBARCODE */
-
-#ifdef HAVE_LIBZINT
-
-	{ "AUSP", N_("Australia Post Standard"), gl_barcode_zint_new,
-	  TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
-
-	{ "AUSRP", N_("Australia Post Reply Paid"), gl_barcode_zint_new,
-	  TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
-
-	{ "AUSRT", N_("Australia Post Route Code"), gl_barcode_zint_new,
-	  TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
-
-	{ "AUSRD", N_("Australia Post Redirect"), gl_barcode_zint_new,
-	  TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
-
-	{ "AZTEC", N_("Aztec Code"), gl_barcode_zint_new,
-	  TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
-	  
-	{ "AZRUN", N_("Aztec Rune"), gl_barcode_zint_new,
-	  TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
-
-	{ "CBR", N_("Codabar"), gl_barcode_zint_new,
-	  TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
-
-	{ "Code1", N_("Code One"),  gl_barcode_zint_new,
-	  TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
-
-	{ "Code11", N_("Code 11"), gl_barcode_zint_new,
-	  TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
-	  
-	{ "C16K", N_("Code 16K"), gl_barcode_zint_new,
-	  TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
-	  
-	{ "C25M", N_("Code 2 of 5 Matrix"),  gl_barcode_zint_new,
-	  TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
-	  
-	{ "C25I", N_("Code 2 of 5 IATA"),  gl_barcode_zint_new,
-	  TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
-	  
-	{ "C25DL", N_("Code 2 of 5 Data Logic"),  gl_barcode_zint_new,
-	  TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
-
-	{ "Code32", N_("Code 32 (Italian Pharmacode)"),  gl_barcode_zint_new,
-	  TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
-
-	{ "Code39", N_("Code 39"), gl_barcode_zint_new,
-	  TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
-	  
-	{ "Code39E", N_("Code 39 Extended"),  gl_barcode_zint_new,
-	  TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
-
-	{ "Code49", N_("Code 49"), gl_barcode_zint_new,
-	  TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
-
-	{ "Code93", N_("Code 93"), gl_barcode_zint_new,
-	  TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
-
-	{ "Code128", N_("Code 128"), gl_barcode_zint_new,
-	  TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
-	  
-	{ "Code128B", N_("Code 128 (Mode C supression)"), gl_barcode_zint_new,
-	  TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
-	  
-	{ "DAFT", N_("DAFT Code"), gl_barcode_zint_new,
-	  TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
-
-	{ "DMTX", N_("Data Matrix"), gl_barcode_zint_new,
-	  TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
-
-	{ "DPL", N_("Deutsche Post Leitcode"), gl_barcode_zint_new,
-	  TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
-	  
-	{ "DPI", N_("Deutsche Post Identcode"), gl_barcode_zint_new,
-	  TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
-	  
-	{ "KIX", N_("Dutch Post KIX Code"), gl_barcode_zint_new,
-	  TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
-
-	{ "EAN", N_("European Article Number (EAN)"), gl_barcode_zint_new,
-	  TRUE, TRUE, TRUE, FALSE, "000000000000", FALSE, 13},
-
-	{ "GMTX", N_("Grid Matrix"),  gl_barcode_zint_new,
-	  TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
-
-        { "GS1-128", N_("GS1-128"), gl_barcode_zint_new,
-	  TRUE, TRUE, TRUE, FALSE, "[01]00000000000000", FALSE, 18},
-
-	{ "RSS14", N_("GS1 DataBar-14"), gl_barcode_zint_new,
-	  TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
-	  
-	{ "RSSLTD", "GS1 DataBar-14 Limited",  gl_barcode_zint_new,
-	  TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
-	  
-	{ "RSSEXP", "GS1 DataBar Extended",  gl_barcode_zint_new,
-	  TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
-	  
-	{ "RSSS", N_("GS1 DataBar-14 Stacked"), gl_barcode_zint_new,
-	  TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
-
-	{ "RSSSO", N_("GS1 DataBar-14 Stacked Omni."), gl_barcode_zint_new,
-	  TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
-
-	{ "RSSSE", N_("GS1 DataBar Extended Stacked"), gl_barcode_zint_new,
-	  TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
-
-	{ "HIBC128", N_("HIBC Code 128"), gl_barcode_zint_new,
-	  TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
-
-	{ "HIBC39", N_("HIBC Code 39"), gl_barcode_zint_new,
-	  TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
-
-	{ "HIBCDM", N_("HIBC Data Matrix"), gl_barcode_zint_new,
-	  TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
-
-	{ "HIBCQR", N_("HIBC QR Code"), gl_barcode_zint_new,
-	  TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
-
-	{ "HIBCPDF", N_("HIBC PDF417"), gl_barcode_zint_new,
-	  TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
-
-	{ "HIBCMPDF", N_("HIBC Micro PDF417"), gl_barcode_zint_new,
-	  TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
-
-	{ "HIBCAZ", N_("HIBC Aztec Code"), gl_barcode_zint_new,
-	  TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
-
-	{ "I25", N_("Interleaved 2 of 5"), gl_barcode_zint_new,
-	  TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
-
-	{ "ISBN", N_("ISBN"), gl_barcode_zint_new,
-	  TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
-
-	{ "ITF14", N_("ITF-14"), gl_barcode_zint_new,
-	  TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
-
-	{ "JAPAN", N_("Japanese Postal"), gl_barcode_zint_new,
-	  TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
-
-	{ "KOREA", N_("Korean Postal"), gl_barcode_zint_new,
-	  TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
-
-	{ "LOGM", N_("LOGMARS"), gl_barcode_zint_new,
-	  TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
-
-	{ "MPDF", N_("Micro PDF417"), gl_barcode_zint_new,
-	  TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
-
-	{ "MQR", N_("Micro QR Code"), gl_barcode_zint_new,
-	  TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
-
-	{ "MSI", N_("MSI Plessey"), gl_barcode_zint_new,
-	  TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
-
-	{ "NVE", N_("NVE-18"), gl_barcode_zint_new,
-	  TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
-
-	{ "PDF", N_("PDF417"), gl_barcode_zint_new,
-	  TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
-
-	{ "PDFT", N_("PDF417 Truncated"), gl_barcode_zint_new,
-	  TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
-
-	{ "PLAN", N_("PLANET"), gl_barcode_zint_new,
-	  TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
-
-	{ "POSTNET", N_("PostNet"), gl_barcode_zint_new,
-	  TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
-
-	{ "PHARMA", N_("Pharmacode"), gl_barcode_zint_new,
-	  TRUE, TRUE, TRUE, FALSE, "00000", TRUE, 5},
-
-	{ "PHARMA2", N_("Pharmacode 2-track"), gl_barcode_zint_new,
-	  TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
-
-	{ "PZN", N_("Pharmazentral Nummer (PZN)"), gl_barcode_zint_new,
-	  TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
-
-	{ "QR", N_("QR Code"), gl_barcode_zint_new,
-	  TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
-
-	{ "RM4", N_("Royal Mail 4-State"), gl_barcode_zint_new,
-	  TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
-
-	{ "TELE", N_("Telepen"), gl_barcode_zint_new,
-	  TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
-
-	{ "TELEX", N_("Telepen Numeric"), gl_barcode_zint_new,
-	  TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
-
-	{ "UPC-A", N_("UPC-A"),  gl_barcode_zint_new,
-	  TRUE, TRUE, TRUE, FALSE, "00000000000", FALSE, 11},
-	  
-	{ "UPC-E", N_("UPC-E"),  gl_barcode_zint_new,
-	  TRUE, TRUE, TRUE, FALSE, "000000", FALSE, 6},
-	  
-	{ "USPS", N_("USPS One Code"), gl_barcode_zint_new,
-	  TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
-
-	{ "PLS", N_("UK Plessey"), gl_barcode_zint_new,
-	  TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
-
-#endif /* HAVE_LIBZINT */
-
-#ifdef HAVE_LIBIEC16022
-
-	{ "IEC16022", N_("IEC16022 (DataMatrix)"), gl_barcode_iec16022_new,
-	  FALSE, FALSE, TRUE, FALSE, "12345678", TRUE, 8},
-
-#endif /* HAVE_LIBIEC16022 */
-
-#ifdef HAVE_LIBQRENCODE
-
-	{ "IEC18004", N_("IEC18004 (QRCode)"), gl_barcode_iec18004_new,
-	  FALSE, FALSE, TRUE, FALSE, "12345678", TRUE, 8},
-
-#endif /* HAVE_LIBQRENCODE */
-
-	{ NULL, NULL, NULL, FALSE, FALSE, FALSE, FALSE, NULL, FALSE, 0}
-
-};
-
 
 /*========================================================*/
 /* Private function prototypes.                           */
@@ -388,75 +59,13 @@ static void gl_barcode_add_shape        (glBarcode      *bc,
 static void gl_barcode_shape_free       (glBarcodeShape *shape);
 
 
-/*---------------------------------------------------------------------------*/
-/* Convert id to index into above table.                                     */
-/*---------------------------------------------------------------------------*/
-static gint
-id_to_index (const gchar *id)
-{
-	gint i;
-
-	if (id == 0) {
-		return 0; /* NULL request default. I.e., the first element. */
-	}
-
-	for (i=0; backends[i].id != NULL; i++) {
-		if (g_ascii_strcasecmp (id, backends[i].id) == 0) {
-			return i;
-		}
-	}
-
-	g_message( "Unknown barcode id \"%s\"", id );
-	return 0;
-}
-
-
-/*---------------------------------------------------------------------------*/
-/* Convert name to index into above table.                                   */
-/*---------------------------------------------------------------------------*/
-static gint
-name_to_index (const gchar *name)
-{
-	gint i;
-
-	g_return_val_if_fail (name!=NULL, 0);
-
-	for (i=0; backends[i].id != NULL; i++) {
-		if (strcmp (name, gettext (backends[i].name)) == 0) {
-			return i;
-		}
-	}
-
-	g_message( "Unknown barcode name \"%s\"", name );
-	return 0;
-}
-
-
 /*****************************************************************************/
-/* Call appropriate barcode backend to create barcode in intermediate format.*/
+/* Allocate new empty glBarcode structure.                                   */
 /*****************************************************************************/
 glBarcode *
-gl_barcode_new (const gchar    *id,
-		gboolean        text_flag,
-		gboolean        checksum_flag,
-		gdouble         w,
-		gdouble         h,
-		const gchar    *digits)
+gl_barcode_new (void)
 {
-	glBarcode *gbc;
-	gint       i;
-
-	g_return_val_if_fail (digits!=NULL, NULL);
-
-	i = id_to_index (id);
-	gbc = backends[i].new (backends[i].id,
-			       text_flag,
-			       checksum_flag,
-			       w,
-			       h,
-			       digits);
-
-	return gbc;
+        return g_new0 (glBarcode, 1);
 }
 
 
@@ -466,20 +75,22 @@ gl_barcode_new (const gchar    *id,
 void
 gl_barcode_free (glBarcode **gbc)
 {
-	GList *p;
+        GList *p;
 
-	if (*gbc != NULL) {
+        if (*gbc != NULL)
+        {
 
-		for (p = (*gbc)->shapes; p != NULL; p = p->next) {
-			gl_barcode_shape_free ((glBarcodeShape *)p->data);
-			p->data = NULL;
-		}
-		g_list_free ((*gbc)->shapes);
-		(*gbc)->shapes = NULL;
+                for (p = (*gbc)->shapes; p != NULL; p = p->next)
+                {
+                        gl_barcode_shape_free ((glBarcodeShape *)p->data);
+                        p->data = NULL;
+                }
+                g_list_free ((*gbc)->shapes);
+                (*gbc)->shapes = NULL;
 
-		g_free (*gbc);
-		*gbc = NULL;
-	}
+                g_free (*gbc);
+                *gbc = NULL;
+        }
 }
 
 
@@ -579,8 +190,8 @@ static void
 gl_barcode_add_shape (glBarcode      *bc,
                       glBarcodeShape *shape)
 {
-	g_return_if_fail (bc);
-	g_return_if_fail (shape);
+        g_return_if_fail (bc);
+        g_return_if_fail (shape);
 
         bc->shapes = g_list_prepend (bc->shapes, shape);
 }
@@ -607,138 +218,6 @@ gl_barcode_shape_free (glBarcodeShape *shape)
 }
 
 
-/*****************************************************************************/
-/* Get a list of names for valid barcode styles.                             */
-/*****************************************************************************/
-GList *
-gl_barcode_get_styles_list  (void)
-{
-	gint   i;
-	GList *list = NULL;
-
-	for (i=0; backends[i].id != NULL; i++) {
-		list = g_list_prepend (list, g_strdup (gettext (backends[i].name)));
-	}
-
-	return g_list_reverse (list);
-}
-
-
-/*****************************************************************************/
-/* Free up a previously allocated list of style names.                       */
-/*****************************************************************************/
-void
-gl_barcode_free_styles_list (GList *styles_list)
-{
-	GList *p;
-
-	for (p=styles_list; p != NULL; p=p->next) {
-		g_free (p->data);
-		p->data = NULL;
-	}
-
-	g_list_free (styles_list);
-}
-
-
-/*****************************************************************************/
-/* Return an appropriate set of digits for the given barcode style.          */
-/*****************************************************************************/
-gchar *
-gl_barcode_default_digits (const gchar *id,
-			   guint        n)
-{
-	int i;
-
-	i = id_to_index (id);
-
-	if (backends[i].can_freeform) {
-
-		return g_strnfill (MAX (n,1), '0');
-
-	} else {
-
-		return g_strdup (backends[i].default_digits);
-
-	}
-}
-
-
-/*****************************************************************************/
-/* Query text capabilities.                                                  */
-/*****************************************************************************/
-gboolean
-gl_barcode_can_text (const gchar *id)
-{
-	return backends[id_to_index (id)].can_text;
-}
-
-
-gboolean
-gl_barcode_text_optional (const gchar *id)
-{
-	return backends[id_to_index (id)].text_optional;
-}
-
-
-/*****************************************************************************/
-/* Query checksum capabilities.                                              */
-/*****************************************************************************/
-gboolean
-gl_barcode_can_csum (const gchar *id)
-{
-	return backends[id_to_index (id)].can_checksum;
-}
-
-
-gboolean
-gl_barcode_csum_optional (const gchar *id)
-{
-	return backends[id_to_index (id)].checksum_optional;
-}
-
-
-/*****************************************************************************/
-/* Query if freeform input is allowed.                                       */
-/*****************************************************************************/
-gboolean
-gl_barcode_can_freeform     (const gchar    *id)
-{
-	return backends[id_to_index (id)].can_freeform;
-}
-
-
-/*****************************************************************************/
-/* Query prefered number of digits of input.                                 */
-/*****************************************************************************/
-guint
-gl_barcode_get_prefered_n (const gchar    *id)
-{
-	return backends[id_to_index (id)].prefered_n;
-}
-
-
-/*****************************************************************************/
-/* Convert style to text.                                                    */
-/*****************************************************************************/
-const gchar *
-gl_barcode_id_to_name (const gchar *id)
-{
-	return gettext (backends[id_to_index (id)].name);
-}
-
-
-/*****************************************************************************/
-/* Convert name to style.                                                    */
-/*****************************************************************************/
-const gchar *
-gl_barcode_name_to_id (const gchar *name)
-{
-	g_return_val_if_fail (name!=NULL, backends[0].id);
-
-	return backends[name_to_index (name)].id;
-}
-
 
 
 /*
diff --git a/src/bc.h b/src/bc.h
index c32fbd3..06503c2 100644
--- a/src/bc.h
+++ b/src/bc.h
@@ -31,6 +31,50 @@ G_BEGIN_DECLS
 #define GL_BARCODE_FONT_WEIGHT      PANGO_WEIGHT_NORMAL
 
 
+/********************************/
+/* Barcode Intermediate Format. */
+/********************************/
+
+typedef struct {
+
+        gdouble  width;
+        gdouble  height;
+
+        GList   *shapes;    /* List of glBarcodeShape drawing primitives */
+
+} glBarcode;
+
+
+glBarcode       *gl_barcode_new              (void);
+
+void             gl_barcode_free             (glBarcode     **bc);
+
+void             gl_barcode_add_line         (glBarcode      *bc,
+                                              gdouble         x,
+                                              gdouble         y,
+                                              gdouble         length,
+                                              gdouble         width);
+
+void             gl_barcode_add_box          (glBarcode      *bc,
+                                              gdouble         x,
+                                              gdouble         y,
+                                              gdouble         width,
+                                              gdouble         height);
+
+void             gl_barcode_add_char         (glBarcode      *bc,
+                                              gdouble         x,
+                                              gdouble         y,
+                                              gdouble         fsize,
+                                              gchar           c);
+
+void             gl_barcode_add_string       (glBarcode      *bc,
+                                              gdouble         x,
+                                              gdouble         y,
+                                              gdouble         fsize,
+                                              gchar          *string,
+                                              gsize           length);
+
+
 /*******************************/
 /* Barcode Drawing Primitives. */
 /*******************************/
@@ -180,77 +224,6 @@ typedef union {
 } glBarcodeShape;
 
 
-/********************************/
-/* Barcode Intermediate Format. */
-/********************************/
-
-typedef struct {
-        gdouble width, height;
-        GList *shapes;    /* List of glBarcodeShape */
-} glBarcode;
-
-typedef glBarcode *(*glBarcodeNewFunc)       (const gchar    *id,
-                                              gboolean        text_flag,
-                                              gboolean        checksum_flag,
-                                              gdouble         w,
-                                              gdouble         h,
-                                              const gchar    *digits);
-
-
-glBarcode       *gl_barcode_new              (const gchar    *id,
-                                              gboolean        text_flag,
-                                              gboolean        checksum_flag,
-                                              gdouble         w,
-                                              gdouble         h,
-                                              const gchar    *digits);
-
-void             gl_barcode_free             (glBarcode     **bc);
-
-void             gl_barcode_add_line         (glBarcode      *bc,
-                                              gdouble         x,
-                                              gdouble         y,
-                                              gdouble         length,
-                                              gdouble         width);
-
-void             gl_barcode_add_box          (glBarcode      *bc,
-                                              gdouble         x,
-                                              gdouble         y,
-                                              gdouble         width,
-                                              gdouble         height);
-
-void             gl_barcode_add_char         (glBarcode      *bc,
-                                              gdouble         x,
-                                              gdouble         y,
-                                              gdouble         fsize,
-                                              gchar           c);
-
-void             gl_barcode_add_string       (glBarcode      *bc,
-                                              gdouble         x,
-                                              gdouble         y,
-                                              gdouble         fsize,
-                                              gchar          *string,
-                                              gsize           length);
-
-
-GList           *gl_barcode_get_styles_list  (void);
-void             gl_barcode_free_styles_list (GList          *styles_list);
-
-gchar           *gl_barcode_default_digits   (const gchar    *id,
-                                              guint            n);
-
-gboolean         gl_barcode_can_text         (const gchar    *id);
-gboolean         gl_barcode_text_optional    (const gchar    *id);
-
-gboolean         gl_barcode_can_csum         (const gchar    *id);
-gboolean         gl_barcode_csum_optional    (const gchar    *id);
-
-gboolean         gl_barcode_can_freeform     (const gchar    *id);
-guint            gl_barcode_get_prefered_n   (const gchar    *id);
-
-const gchar     *gl_barcode_id_to_name       (const gchar    *id);
-const gchar     *gl_barcode_name_to_id       (const gchar    *name);
-
-
 G_END_DECLS
 
 #endif /* __BC_H__ */
diff --git a/src/label-barcode.c b/src/label-barcode.c
index 5367261..bb5fba7 100644
--- a/src/label-barcode.c
+++ b/src/label-barcode.c
@@ -25,6 +25,7 @@
 #include <glib.h>
 #include <glib/gi18n.h>
 #include <pango/pangocairo.h>
+#include "bc-backends.h"
 
 #include "debug.h"
 
@@ -323,30 +324,30 @@ get_size (glLabelObject *object,
 	gl_label_object_get_raw_size (object, &w_parent, &h_parent);
 
 	if (lbc->priv->text_node->field_flag) {
-		data = gl_barcode_default_digits (lbc->priv->id,
-						  lbc->priv->format_digits);
+		data = gl_barcode_backends_default_digits (lbc->priv->id,
+                                                           lbc->priv->format_digits);
 	} else {
 		data = gl_text_node_expand (lbc->priv->text_node, NULL);
 	}
 
-	gbc = gl_barcode_new (lbc->priv->id,
-			      lbc->priv->text_flag,
-			      lbc->priv->checksum_flag,
-			      w_parent,
-			      h_parent,
-			      data);
+	gbc = gl_barcode_backends_new_barcode (lbc->priv->id,
+                                               lbc->priv->text_flag,
+                                               lbc->priv->checksum_flag,
+                                               w_parent,
+                                               h_parent,
+                                               data);
 	g_free (data);
 
 	if ( gbc == NULL ) {
 		/* Try again with default digits. */
-		data = gl_barcode_default_digits (lbc->priv->id,
+		data = gl_barcode_backends_default_digits (lbc->priv->id,
 						  lbc->priv->format_digits);
-		gbc = gl_barcode_new (lbc->priv->id,
-				      lbc->priv->text_flag,
-				      lbc->priv->checksum_flag,
-				      w_parent,
-				      h_parent,
-				      data);
+		gbc = gl_barcode_backends_new_barcode (lbc->priv->id,
+                                                       lbc->priv->text_flag,
+                                                       lbc->priv->checksum_flag,
+                                                       w_parent,
+                                                       h_parent,
+                                                       data);
                 g_free (data);
 	}
 
@@ -465,10 +466,10 @@ draw_object (glLabelObject *object,
 	text_node = gl_label_barcode_get_data(GL_LABEL_BARCODE(object));
         text = gl_text_node_expand (text_node, record);
 	if (text_node->field_flag && screen_flag) {
-		text = gl_barcode_default_digits (id, format_digits);
+		text = gl_barcode_backends_default_digits (id, format_digits);
 	}
 
-	gbc = gl_barcode_new (id, text_flag, checksum_flag, w, h, text);
+	gbc = gl_barcode_backends_new_barcode (id, text_flag, checksum_flag, w, h, text);
 
         cairo_set_source_rgba (cr, GL_COLOR_RGBA_ARGS (color));
 
diff --git a/src/label-barcode.h b/src/label-barcode.h
index 388ee5d..3ae672b 100644
--- a/src/label-barcode.h
+++ b/src/label-barcode.h
@@ -21,7 +21,6 @@
 #ifndef __LABEL_BARCODE_H__
 #define __LABEL_BARCODE_H__
 
-#include "bc.h"
 #include "text-node.h"
 #include "label-object.h"
 
diff --git a/src/object-editor-bc-page.c b/src/object-editor-bc-page.c
index 1f4f684..95c2915 100644
--- a/src/object-editor-bc-page.c
+++ b/src/object-editor-bc-page.c
@@ -32,6 +32,7 @@
 #include "field-button.h"
 #include "combo-util.h"
 #include "builder-util.h"
+#include "bc-backends.h"
 
 #include "object-editor-private.h"
 
@@ -105,10 +106,10 @@ gl_object_editor_prepare_bc_page (glObjectEditor       *editor)
 	gl_combo_util_add_text_model ( GTK_COMBO_BOX(editor->priv->bc_style_combo));
 
 	/* Load barcode styles */
-	styles = gl_barcode_get_styles_list ();
+	styles = gl_barcode_backends_get_styles_list ();
 	gl_combo_util_set_strings (GTK_COMBO_BOX(editor->priv->bc_style_combo),
                                    styles);
-	gl_barcode_free_styles_list (styles);
+	gl_barcode_backends_free_styles_list (styles);
 
 	/* Modify widgets */
 	gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (editor->priv->bc_color_radio), TRUE);
@@ -174,23 +175,23 @@ style_changed_cb (glObjectEditor       *editor)
                                                                                 
         /* Don't emit if entry is empty. */
         if ( *style_string != 0 ) {
-                id = gl_barcode_name_to_id (style_string);
+                id = gl_barcode_backends_name_to_id (style_string);
                                                                                 
                 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(editor->priv->bc_text_check),
-					      gl_barcode_can_text (id));
+					      gl_barcode_backends_can_text (id));
                 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(editor->priv->bc_cs_check),
-					      gl_barcode_can_csum (id));
+					      gl_barcode_backends_can_csum (id));
                                                                                 
                 gtk_widget_set_sensitive (editor->priv->bc_text_check,
-                                          gl_barcode_text_optional (id));
+                                          gl_barcode_backends_text_optional (id));
                 gtk_widget_set_sensitive (editor->priv->bc_cs_check,
-                                          gl_barcode_csum_optional (id));
+                                          gl_barcode_backends_csum_optional (id));
                                                                                 
-		editor->priv->data_format_fixed_flag = !gl_barcode_can_freeform (id);
-                digits = gl_barcode_get_prefered_n(id);
+		editor->priv->data_format_fixed_flag = !gl_barcode_backends_can_freeform (id);
+                digits = gl_barcode_backends_get_prefered_n(id);
                 gtk_spin_button_set_value (GTK_SPIN_BUTTON (editor->priv->data_digits_spin), digits);
                                                                                 
-		ex_string = gl_barcode_default_digits (id, digits);
+		ex_string = gl_barcode_backends_default_digits (id, digits);
 		gtk_label_set_text (GTK_LABEL(editor->priv->data_ex_label), ex_string);
 
 		if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (editor->priv->data_literal_radio))) {
@@ -232,7 +233,7 @@ gl_object_editor_set_bc_style (glObjectEditor      *editor,
 
         editor->priv->stop_signals = TRUE;
 
-        style_string = gl_barcode_id_to_name (id);
+        style_string = gl_barcode_backends_id_to_name (id);
  
 	gl_combo_util_set_active_text (GTK_COMBO_BOX (editor->priv->bc_style_combo),
                                        style_string);
@@ -244,17 +245,17 @@ gl_object_editor_set_bc_style (glObjectEditor      *editor,
                                       checksum_flag);
 
 	gtk_widget_set_sensitive (editor->priv->bc_text_check,
-				  gl_barcode_text_optional (id));
+				  gl_barcode_backends_text_optional (id));
 	gtk_widget_set_sensitive (editor->priv->bc_cs_check,
-				  gl_barcode_csum_optional (id));
+				  gl_barcode_backends_csum_optional (id));
 
-	editor->priv->data_format_fixed_flag = !gl_barcode_can_freeform (id);
+	editor->priv->data_format_fixed_flag = !gl_barcode_backends_can_freeform (id);
 
 	if (editor->priv->data_format_fixed_flag) {
-		format_digits = gl_barcode_get_prefered_n (id);
+		format_digits = gl_barcode_backends_get_prefered_n (id);
 	}
 
-	ex_string = gl_barcode_default_digits (id, format_digits);
+	ex_string = gl_barcode_backends_default_digits (id, format_digits);
 	gtk_label_set_text (GTK_LABEL(editor->priv->data_ex_label), ex_string);
 	g_free (ex_string);
 
@@ -297,7 +298,7 @@ gl_object_editor_get_bc_style (glObjectEditor      *editor,
                                                                                 
         style_string =
 		gtk_combo_box_get_active_text (GTK_COMBO_BOX (editor->priv->bc_style_combo));
-        *id = g_strdup (gl_barcode_name_to_id (style_string));
+        *id = g_strdup (gl_barcode_backends_name_to_id (style_string));
                                                                                 
         *text_flag =
             gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (editor->priv->bc_text_check));
@@ -437,10 +438,10 @@ data_digits_spin_changed_cb (glObjectEditor *editor)
 
         style_string = gtk_combo_box_get_active_text (GTK_COMBO_BOX (editor->priv->bc_style_combo));
         if ( *style_string != 0 ) {
-                id = gl_barcode_name_to_id (style_string);
+                id = gl_barcode_backends_name_to_id (style_string);
 
                 digits = gtk_spin_button_get_value (GTK_SPIN_BUTTON (editor->priv->data_digits_spin));
-                ex_string = gl_barcode_default_digits (id, digits);
+                ex_string = gl_barcode_backends_default_digits (id, digits);
                 gtk_label_set_text (GTK_LABEL(editor->priv->data_ex_label), ex_string);
         }
 
diff --git a/src/object-editor.h b/src/object-editor.h
index d8f7095..a51d7e3 100644
--- a/src/object-editor.h
+++ b/src/object-editor.h
@@ -26,7 +26,6 @@
 #include "text-node.h"
 #include "label.h"
 #include "merge.h"
-#include "bc.h"
 #include "color.h"
 
 G_BEGIN_DECLS



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]