]> git.sur5r.net Git - glabels/blobdiff - glabels2/src/bc.c
2009-07-26 Jim Evins <evins@snaught.com>
[glabels] / glabels2 / src / bc.c
index 8c431f1ba3527357d068463368b5a709973343f4..70d72c5b4d5cc4e26ec24e80363f87bc5b93fc50 100644 (file)
@@ -1,3 +1,5 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */
+
 /*
  *  (GLABELS) Label and Business Card Creation program for GNOME
  *
 #include <config.h>
 
 #include "bc.h"
+
+#include <glib/gi18n.h>
+#include <glib/gmem.h>
+#include <glib/gstrfuncs.h>
+#include <glib/gmessages.h>
+
 #include "bc-postnet.h"
 #include "bc-gnubarcode.h"
+#include "bc-iec16022.h"
+#include "bc-iec18004.h"
 
 #include "debug.h"
 
@@ -36,6 +46,7 @@
 /*========================================================*/
 
 typedef struct {
+       gchar            *id;
        gchar            *name;
        glBarcodeNewFunc  new;
        gboolean          can_text;
@@ -43,6 +54,8 @@ typedef struct {
        gboolean          can_checksum;
        gboolean          checksum_optional;
        gchar            *default_digits;
+       gboolean          can_freeform;
+       guint             prefered_n;
 } Backend;
 
 
@@ -50,43 +63,102 @@ typedef struct {
 /* Private globals.                                       */
 /*========================================================*/
 
-Backend backends[GL_BARCODE_N_STYLES] = {
+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},
+
+       { "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},
 
-       { "POSTNET", gl_barcode_postnet_new,
-         FALSE, FALSE, TRUE, FALSE, "000000000"},
+       { "UPC-A", N_("UPC-A"), gl_barcode_gnubarcode_new,
+         TRUE, TRUE, TRUE, FALSE, "00000000000", FALSE, 11},
 
-       { "EAN", gl_barcode_gnubarcode_new,
-         TRUE, TRUE, TRUE, FALSE, "000000000000 00000"},
+       { "UPC-A+2", N_("UPC-A +2"), gl_barcode_gnubarcode_new,
+         TRUE, TRUE, TRUE, FALSE, "00000000000 00", FALSE, 13},
 
-       { "UPC", gl_barcode_gnubarcode_new,
-         TRUE, TRUE, TRUE, FALSE, "00000000000 00000"},
+       { "UPC-A+5", N_("UPC-A +5"), gl_barcode_gnubarcode_new,
+         TRUE, TRUE, TRUE, FALSE, "00000000000 00000", FALSE, 16},
 
-       { "ISBN", gl_barcode_gnubarcode_new,
-         TRUE, TRUE, TRUE, TRUE, "0-00000-000-0 00000"},
+       { "UPC-E", N_("UPC-E"), gl_barcode_gnubarcode_new,
+         TRUE, TRUE, TRUE, FALSE, "000000", FALSE, 6},
 
-       { "Code39", gl_barcode_gnubarcode_new,
-         TRUE, TRUE, TRUE, TRUE, "0000000000"},
+       { "UPC-E+2", N_("UPC-E +2"), gl_barcode_gnubarcode_new,
+         TRUE, TRUE, TRUE, FALSE, "000000 00", FALSE, 8},
 
-       { "Code128", gl_barcode_gnubarcode_new,
-         TRUE, TRUE, TRUE, TRUE, "0000000000"},
+       { "UPC-E+5", N_("UPC-E +5"), gl_barcode_gnubarcode_new,
+         TRUE, TRUE, TRUE, FALSE, "000000 00000", FALSE, 11},
 
-       { "Code128C", gl_barcode_gnubarcode_new,
-         TRUE, TRUE, TRUE, TRUE, "0000000000"},
+       { "ISBN", N_("ISBN"), gl_barcode_gnubarcode_new,
+         TRUE, TRUE, TRUE, TRUE, "0-00000-000-0", FALSE, 10},
 
-       { "Code128B", gl_barcode_gnubarcode_new,
-         TRUE, TRUE, TRUE, TRUE, "0000000000"},
+       { "ISBN+5", N_("ISBN +5"), gl_barcode_gnubarcode_new,
+         TRUE, TRUE, TRUE, TRUE, "0-00000-000-0 00000", FALSE, 15},
 
-       { "I25", gl_barcode_gnubarcode_new,
-         TRUE, TRUE, TRUE, TRUE, "0000000000"},
+       { "Code39", N_("Code 39"), gl_barcode_gnubarcode_new,
+         TRUE, TRUE, TRUE, TRUE, "0000000000", TRUE, 10},
 
-       { "CBR", gl_barcode_gnubarcode_new,
-         TRUE, TRUE, TRUE, TRUE, "0000000000"},
+       { "Code128", N_("Code 128"), gl_barcode_gnubarcode_new,
+         TRUE, TRUE, TRUE, TRUE, "0000000000", TRUE, 10},
 
-       { "MSI", gl_barcode_gnubarcode_new,
-         TRUE, TRUE, TRUE, TRUE, "0000000000"},
+       { "Code128C", N_("Code 128C"), gl_barcode_gnubarcode_new,
+         TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
 
-       { "PLS", gl_barcode_gnubarcode_new,
-         TRUE, TRUE, TRUE, TRUE, "0000000000"},
+       { "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},
+
+       { "IEC16022", N_("IEC16022 (DataMatrix)"), gl_barcode_iec16022_new,
+         FALSE, FALSE, TRUE, FALSE, "12345678", TRUE, 8},
+
+       { "IEC18004", N_("IEC18004 (QRCode)"), gl_barcode_iec18004_new,
+         FALSE, FALSE, TRUE, FALSE, "12345678", TRUE, 8},
+
+       { NULL, NULL, NULL, FALSE, FALSE, FALSE, FALSE, NULL, FALSE, 0}
 
 };
 
@@ -95,28 +167,71 @@ Backend backends[GL_BARCODE_N_STYLES] = {
 /*========================================================*/
 
 \f
+/*---------------------------------------------------------------------------*/
+/* 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_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 (g_strcasecmp (name, 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.*/
 /*****************************************************************************/
 glBarcode *
-gl_barcode_new (glBarcodeStyle  style,
+gl_barcode_new (const gchar    *id,
                gboolean        text_flag,
                gboolean        checksum_flag,
                gdouble         w,
                gdouble         h,
-               gchar          *digits)
+               const gchar    *digits)
 {
        glBarcode *gbc;
+       gint       i;
 
-       g_return_val_if_fail ((style>=0) && (style<GL_BARCODE_N_STYLES), NULL);
        g_return_val_if_fail (digits!=NULL, NULL);
 
-       gbc = backends[style].new (style,
-                                  text_flag,
-                                  checksum_flag,
-                                  w,
-                                  h,
-                                  digits);
+       i = id_to_index (id);
+       gbc = backends[i].new (backends[i].id,
+                              text_flag,
+                              checksum_flag,
+                              w,
+                              h,
+                              digits);
 
        return gbc;
 }
@@ -156,11 +271,11 @@ gl_barcode_free (glBarcode **gbc)
 GList *
 gl_barcode_get_styles_list  (void)
 {
-       glBarcodeStyle  style;
-       GList          *list = NULL;
+       gint   i;
+       GList *list = NULL;
 
-       for (style=0; style <GL_BARCODE_N_STYLES; style++) {
-               list = g_list_append (list, g_strdup (backends[style].name));
+       for (i=0; backends[i].id != NULL; i++) {
+               list = g_list_append (list, g_strdup (backends[i].name));
        }
 
        return list;
@@ -187,77 +302,89 @@ gl_barcode_free_styles_list (GList *styles_list)
 /* Return an appropriate set of digits for the given barcode style.          */
 /*****************************************************************************/
 gchar *
-gl_barcode_default_digits (glBarcodeStyle style)
+gl_barcode_default_digits (const gchar *id,
+                          guint        n)
 {
-       g_return_val_if_fail ((style>=0) && (style<GL_BARCODE_N_STYLES), "0");
+       int i;
 
-       return g_strdup (backends[style].default_digits);
+       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 (glBarcodeStyle  style)
+gl_barcode_can_text (const gchar *id)
 {
-       g_return_val_if_fail ((style>=0) && (style<GL_BARCODE_N_STYLES), FALSE);
-
-       return backends[style].can_text;
+       return backends[id_to_index (id)].can_text;
 }
 
 gboolean
-gl_barcode_text_optional (glBarcodeStyle  style)
+gl_barcode_text_optional (const gchar *id)
 {
-       g_return_val_if_fail ((style>=0) && (style<GL_BARCODE_N_STYLES), FALSE);
-
-       return backends[style].text_optional;
+       return backends[id_to_index (id)].text_optional;
 }
 
 /*****************************************************************************/
 /* Query checksum capabilities.                                              */
 /*****************************************************************************/
 gboolean
-gl_barcode_can_csum (glBarcodeStyle  style)
+gl_barcode_can_csum (const gchar *id)
 {
-       g_return_val_if_fail ((style>=0) && (style<GL_BARCODE_N_STYLES), FALSE);
+       return backends[id_to_index (id)].can_checksum;
+}
 
-       return backends[style].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_csum_optional (glBarcodeStyle  style)
+gl_barcode_can_freeform     (const gchar    *id)
 {
-       g_return_val_if_fail ((style>=0) && (style<GL_BARCODE_N_STYLES), FALSE);
+       return backends[id_to_index (id)].can_freeform;
+}
 
-       return backends[style].checksum_optional;
+/*****************************************************************************/
+/* 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_style_to_text (glBarcodeStyle style)
+gl_barcode_id_to_name (const gchar *id)
 {
-       g_return_val_if_fail ((style>=0) && (style<GL_BARCODE_N_STYLES), NULL);
-
-       return backends[style].name;
+       return backends[id_to_index (id)].name;
 }
 
 /*****************************************************************************/
-/* Convert text to style.                                                    */
+/* Convert name to style.                                                    */
 /*****************************************************************************/
-glBarcodeStyle
-gl_barcode_text_to_style (const gchar *text)
+const gchar *
+gl_barcode_name_to_id (const gchar *name)
 {
+       g_return_val_if_fail (name!=NULL, backends[0].id);
 
-       glBarcodeStyle  style;
-
-       for (style=0; style <GL_BARCODE_N_STYLES; style++) {
-               if (g_strcasecmp (text, backends[style].name) == 0) {
-                       return style;
-               }
-       }
-
-       g_warning( "Unknown barcode style text \"%s\"", text );
-       return GL_BARCODE_STYLE_POSTNET;
+       return backends[name_to_index (name)].id;
 }