[glabels] Refactored core barcode subsystem.



commit edaa3e0b6dec8f8ba81c05b5a196a90b1ebb1ca2
Author: Jim Evins <evins snaught com>
Date:   Sat Oct 30 17:37:37 2010 -0400

    Refactored core barcode subsystem.
    
    - Created new libglbarcode library
    - Moved core barcode structure into library
    - Moved cairo rendering of barcode into library
    - Moved built-in barcodes to library
    - Resurrected Code39 support (from wayback in glabels 0.1.x)
    
    - Backend "glue" remains in glabels proper

 .gitignore                                         |    2 +
 Makefile.am                                        |    1 +
 configure.ac                                       |   48 +++
 libglbarcode/Makefile.am                           |   51 +++
 libglbarcode/lgl-barcode-code39.c                  |  403 ++++++++++++++++++++
 .../lgl-barcode-code39.h                           |   25 +-
 libglbarcode/lgl-barcode-create.c                  |   99 +++++
 .../lgl-barcode-create.h                           |   28 +-
 .../lgl-barcode-onecode.c                          |  260 +++++++------
 .../lgl-barcode-onecode.h                          |   23 +-
 libglbarcode/lgl-barcode-postnet.c                 |  272 +++++++++++++
 .../lgl-barcode-postnet.h                          |   25 +-
 libglbarcode/lgl-barcode-render-to-cairo.c         |  195 ++++++++++
 .../lgl-barcode-render-to-cairo.h                  |   19 +-
 .../lgl-barcode-type.h                             |   34 +-
 libglbarcode/lgl-barcode.c                         |  257 +++++++++++++
 libglbarcode/lgl-barcode.h                         |  317 +++++++++++++++
 libglbarcode/libglbarcode-3.0.pc.in                |   12 +
 src/bc-postnet.h => libglbarcode/libglbarcode.h    |   26 +-
 src/Makefile.am                                    |   26 +-
 src/bc-backends.c                                  |   41 ++-
 src/bc-backends.h                                  |    4 +-
 src/bc-builtin.c                                   |   97 +++++
 src/{bc-postnet.h => bc-builtin.h}                 |   23 +-
 src/bc-gnubarcode.c                                |   20 +-
 src/bc-gnubarcode.h                                |   14 +-
 src/bc-iec16022.c                                  |   24 +-
 src/bc-iec16022.h                                  |   14 +-
 src/bc-iec18004.c                                  |   24 +-
 src/bc-iec18004.h                                  |   14 +-
 src/bc-postnet.c                                   |  225 -----------
 src/bc-zint.c                                      |   26 +-
 src/bc-zint.h                                      |   14 +-
 src/label-barcode.c                                |  127 +------
 34 files changed, 2123 insertions(+), 667 deletions(-)
---
diff --git a/.gitignore b/.gitignore
index ca04282..84676e3 100644
--- a/.gitignore
+++ b/.gitignore
@@ -66,6 +66,8 @@ glabels-*.tar.gz
 /help/*/*.mo
 /help/*/glabels*.xml
 !/help/C/glabels*.xml
+/help/*/*.page
+!/help/C/*.page
 
 /docs/libglabels/*.stamp
 /docs/libglabels/xml/
diff --git a/Makefile.am b/Makefile.am
index efc7f29..b2dee28 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -3,6 +3,7 @@
 SUBDIRS = \
 	po \
 	libglabels \
+	libglbarcode \
 	src \
 	data \
 	templates \
diff --git a/configure.ac b/configure.ac
index 836e342..37b047d 100644
--- a/configure.ac
+++ b/configure.ac
@@ -45,6 +45,12 @@ LIBGLABELS_BRANCH=libglabels-3.0
 AC_SUBST(LIBGLABELS_BRANCH)
 
 dnl ---------------------------------------------------------------------------
+dnl - LIBGLBARCODE branch
+dnl ---------------------------------------------------------------------------
+LIBGLBARCODE_BRANCH=libglbarcode-3.0
+AC_SUBST(LIBGLBARCODE_BRANCH)
+
+dnl ---------------------------------------------------------------------------
 dnl - LIBGLABELS API versioning
 dnl ---------------------------------------------------------------------------
 dnl From the libtool manual:
@@ -67,6 +73,28 @@ LIBGLABELS_API_VERSION=${LIBGLABELS_C}:${LIBGLABELS_R}:${LIBGLABELS_A}
 AC_SUBST(LIBGLABELS_API_VERSION)
 
 dnl ---------------------------------------------------------------------------
+dnl - LIBGLBARCODE API versioning
+dnl ---------------------------------------------------------------------------
+dnl From the libtool manual:
+dnl 1. Start with version information of `0:0:0' for each libtool library.
+dnl 2. Update the version information only immediately before a public release.
+dnl    More frequent updates are unnecessary, and only guarantee that the current
+dnl    interface number gets larger faster.
+dnl 3. If the library source code has changed at all since the last update, then increment
+dnl    revision (`c:r:a' becomes `c:r+1:a').
+dnl 4. If any interfaces have been added, removed, or changed since the last update,
+dnl    increment current, and set revision to 0.
+dnl 5. If any interfaces have been added since the last public release, then increment age.
+dnl 6. If any interfaces have been removed since the last public release, then set age
+dnl    to 0.
+LIBGLBARCODE_C=0
+LIBGLBARCODE_R=0
+LIBGLBARCODE_A=0
+
+LIBGLBARCODE_API_VERSION=${LIBGLBARCODE_C}:${LIBGLBARCODE_R}:${LIBGLBARCODE_A}
+AC_SUBST(LIBGLBARCODE_API_VERSION)
+
+dnl ---------------------------------------------------------------------------
 dnl - Library dependencies
 dnl ---------------------------------------------------------------------------
 dnl Required dependencies
@@ -75,6 +103,8 @@ GTK_REQUIRED=2.20.0
 GCONF_REQUIRED=2.28.0
 LIBXML_REQUIRED=2.7.0
 LIBRSVG_REQUIRED=2.26.0
+CAIRO_REQUIRED=1.8.0
+PANGO_REQUIRED=1.28.0
 
 dnl Optional dependencies
 LIBEBOOK_REQUIRED=2.28.0
@@ -88,6 +118,9 @@ AC_SUBST(GLIB_REQUIRED)
 AC_SUBST(GTK_REQUIRED)
 AC_SUBST(GCONF_REQUIRED)
 AC_SUBST(LIBXML_REQUIRED)
+AC_SUBST(LIBRSVG_REQUIRED)
+AC_SUBST(CAIRO_REQUIRED)
+AC_SUBST(PANGO_REQUIRED)
 AC_SUBST(LIBEBOOK_REQUIRED)
 AC_SUBST(LIBBARCODE_REQUIRED)
 AC_SUBST(LIBQRENCODE_REQUIRED)
@@ -124,6 +157,19 @@ AC_SUBST(LIBGLABELS_LIBS)
 
 
 dnl ---------------------------------------------------------------------------
+dnl - LIBGLBARCODE more modest prerequisites
+dnl ---------------------------------------------------------------------------
+PKG_CHECK_MODULES(LIBGLBARCODE, [\
+	glib-2.0 >= $GLIB_REQUIRED \
+	cairo >= $CAIRO_REQUIRED \
+	pango >= $PANGO_REQUIRED \
+])
+
+AC_SUBST(LIBGLBARCODE_CFLAGS)
+AC_SUBST(LIBGLBARCODE_LIBS)
+
+
+dnl ---------------------------------------------------------------------------
 dnl - Check for optional evolution data server
 dnl ---------------------------------------------------------------------------
 AC_ARG_WITH(libebook,
@@ -271,6 +317,8 @@ AC_CONFIG_FILES([
 Makefile
 libglabels/Makefile
 libglabels/${LIBGLABELS_BRANCH}.pc
+libglbarcode/Makefile
+libglbarcode/${LIBGLBARCODE_BRANCH}.pc
 src/Makefile
 src/pixmaps/Makefile
 data/Makefile
diff --git a/libglbarcode/Makefile.am b/libglbarcode/Makefile.am
new file mode 100644
index 0000000..7a884df
--- /dev/null
+++ b/libglbarcode/Makefile.am
@@ -0,0 +1,51 @@
+configdir = $(datadir)/$(LIBGLBARCODE_BRANCH)
+
+INCLUDES = \
+	$(LIBGLBARCODE_CFLAGS)				\
+	-DLIBGLBARCODE_CONFIG_DIR=\""$(configdir)"\" \
+	$(DISABLE_DEPRECATED_CFLAGS)
+
+libglbarcode_3_0_la_LDFLAGS=\
+        -version-info $(LIBGLBARCODE_API_VERSION) \
+        $(LIBGLBARCODE_LIBS) \
+        -no-undefined 
+
+lib_LTLIBRARIES = libglbarcode-3.0.la
+
+libglbarcode_3_0_la_SOURCES =		\
+	lgl-barcode.c			\
+	lgl-barcode.h			\
+	lgl-barcode-create.c		\
+	lgl-barcode-create.h		\
+	lgl-barcode-render-to-cairo.c	\
+	lgl-barcode-render-to-cairo.h	\
+	lgl-barcode-type.h		\
+	lgl-barcode-onecode.c		\
+	lgl-barcode-onecode.h		\
+	lgl-barcode-postnet.c		\
+	lgl-barcode-postnet.h		\
+	lgl-barcode-code39.c		\
+	lgl-barcode-code39.h
+
+libglbarcode_3_0includedir=$(includedir)/$(LIBGLBARCODE_BRANCH)
+
+libglbarcode_3_0include_HEADERS = 	\
+	libglbarcode.h
+
+libglbarcode_3_0subincludedir=$(includedir)/$(LIBGLBARCODE_BRANCH)/libglbarcode
+
+libglbarcode_3_0subinclude_HEADERS = 	\
+	lgl-barcode.h			\
+	lgl-barcode-create.h		\
+	lgl-barcode-render-to-cairo.h	\
+	lgl-barcode-type.h		\
+	lgl-barcode-onecode.h		\
+	lgl-barcode-postnet.h		\
+	lgl-barcode-code39.h
+
+EXTRA_DIST =			\
+	$(LIBGLBARCODE_BRANCH).pc.in
+
+pkgconfigdir = $(libdir)/pkgconfig
+pkgconfig_DATA = $(LIBGLBARCODE_BRANCH).pc
+
diff --git a/libglbarcode/lgl-barcode-code39.c b/libglbarcode/lgl-barcode-code39.c
new file mode 100644
index 0000000..4393fc2
--- /dev/null
+++ b/libglbarcode/lgl-barcode-code39.c
@@ -0,0 +1,403 @@
+/*
+ *  lgl-barcode-code39.c
+ *  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/>.
+ */
+
+#include <config.h>
+
+#include "lgl-barcode-code39.h"
+
+#include <glib.h>
+#include <ctype.h>
+#include <string.h>
+
+
+/*========================================================*/
+/* Private macros and constants.                          */
+/*========================================================*/
+
+#define PTS_PER_INCH 72.0
+
+#define MIN_X        ( 0.01 *  PTS_PER_INCH )
+#define N            2.5
+#define MIN_I        MIN_X
+#define MIN_HEIGHT   ( 0.25 *  PTS_PER_INCH )
+#define MIN_QUIET    ( 0.10 *  PTS_PER_INCH )
+
+#define INK_BLEED    ( 0.00325 * PTS_PER_INCH )
+
+#define TEXT_AREA_HEIGHT 14.0
+#define TEXT_SIZE        10.0
+
+
+/*========================================================*/
+/* Private types.                                         */
+/*========================================================*/
+
+typedef struct {
+        gchar  c;
+        gchar *sym;
+} Code39Symbol;
+
+
+/*===========================================*/
+/* Private globals                           */
+/*===========================================*/
+
+static Code39Symbol symbols[] = {
+        /*      BsBsBsBsB */
+        { '0', "NnNwWnWnN" },
+        { '1', "WnNwNnNnW" },
+        { '2', "NnWwNnNnW" },
+        { '3', "WnWwNnNnN" },
+        { '4', "NnNwWnNnW" },
+        { '5', "WnNwWnNnN" },
+        { '6', "NnWwWnNnN" },
+        { '7', "NnNwNnWnW" },
+        { '8', "WnNwNnWnN" },
+        { '9', "NnWwNnWnN" },
+        { 'A', "WnNnNwNnW" },
+        { 'B', "NnWnNwNnW" },
+        { 'C', "WnWnNwNnN" },
+        { 'D', "NnNnWwNnW" },
+        { 'E', "WnNnWwNnN" },
+        { 'F', "NnWnWwNnN" },
+        { 'G', "NnNnNwWnW" },
+        { 'H', "WnNnNwWnN" },
+        { 'I', "NnWnNwWnN" },
+        { 'J', "NnNnWwWnN" },
+        { 'K', "WnNnNnNwW" },
+        { 'L', "NnWnNnNwW" },
+        { 'M', "WnWnNnNwN" },
+        { 'N', "NnNnWnNwW" },
+        { 'O', "WnNnWnNwN" },
+        { 'P', "NnWnWnNwN" },
+        { 'Q', "NnNnNnWwW" },
+        { 'R', "WnNnNnWwN" },
+        { 'S', "NnWnNnWwN" },
+        { 'T', "NnNnWnWwN" },
+        { 'U', "WwNnNnNnW" },
+        { 'V', "NwWnNnNnW" },
+        { 'W', "WwWnNnNnN" },
+        { 'X', "NwNnWnNnW" },
+        { 'Y', "WwNnWnNnN" },
+        { 'Z', "NwWnWnNnN" },
+        { '-', "NwNnNnWnW" },
+        { '.', "WwNnNnWnN" },
+        { ' ', "NwWnNnWnN" },
+        { '$', "NwNwNwNnN" },
+        { '/', "NwNwNnNwN" },
+        { '+', "NwNnNwNwN" },
+        { '%', "NnNwNwNwN" },
+        { 0, NULL }
+};
+
+static gchar *frame_symbol = "NwNnWnWnN";
+
+static gchar *ascii_map[128] =
+{
+        /* NUL */ "%U",   /* SOH */ "$A",   /* STX */ "$B",   /* ETX */ "$C",
+        /* EOT */ "$D",   /* ENQ */ "$E",   /* ACK */ "$F",   /* BEL */ "$G",
+        /* BS  */ "$H",   /* HT  */ "$I",   /* LF  */ "$J",   /* VT  */ "$K",
+        /* FF  */ "$L",   /* CR  */ "$M",   /* SO  */ "$N",   /* SI  */ "$O",
+        /* DLE */ "$P",   /* DC1 */ "$Q",   /* DC2 */ "$R",   /* DC3 */ "$S",
+        /* DC4 */ "$T",   /* NAK */ "$U",   /* SYN */ "$V",   /* ETB */ "$W",
+        /* CAN */ "$X",   /* EM  */ "$Y",   /* SUB */ "$Z",   /* ESC */ "%A",
+        /* FS  */ "%B",   /* GS  */ "%C",   /* RS  */ "%D",   /* US  */ "%E",
+        /* " " */ " ",    /* !   */ "/A",   /* "   */ "/B",   /* #   */ "/C",
+        /* $   */ "/D",   /* %   */ "/E",   /* &   */ "/F",   /* '   */ "/G",
+        /* (   */ "/H",   /* )   */ "/I",   /* *   */ "/J",   /* +   */ "/K",
+        /* ,   */ "/L",   /* -   */ "-",    /* .   */ ".",    /* /   */ "/O",
+        /* 0   */ "0",    /* 1   */ "1",    /* 2   */ "2",    /* 3   */ "3",
+        /* 4   */ "4",    /* 5   */ "5",    /* 6   */ "6",    /* 7   */ "7",
+        /* 8   */ "8",    /* 9   */ "9",    /* :   */ "/Z",   /* ;   */ "%F",
+        /* <   */ "%G",   /* =   */ "%H",   /* >   */ "%I",   /* ?   */ "%J",
+        /* @   */ "%V",   /* A   */ "A",    /* B   */ "B",    /* C   */ "C",
+        /* D   */ "D",    /* E   */ "E",    /* F   */ "F",    /* G   */ "G",
+        /* H   */ "H",    /* I   */ "I",    /* J   */ "J",    /* K   */ "K",
+        /* L   */ "L",    /* M   */ "M",    /* N   */ "N",    /* O   */ "O",
+        /* P   */ "P",    /* Q   */ "Q",    /* R   */ "R",    /* S   */ "S",
+        /* T   */ "T",    /* U   */ "U",    /* V   */ "V",    /* W   */ "W",
+        /* X   */ "X",    /* Y   */ "Y",    /* Z   */ "Z",    /* [   */ "%K",
+        /* \   */ "%L",   /* ]   */ "%M",   /* ^   */ "%N",   /* _   */ "%O",
+        /* `   */ "%W",   /* a   */ "+A",   /* b   */ "+B",   /* c   */ "+C",
+        /* d   */ "+D",   /* e   */ "+E",   /* f   */ "+F",   /* g   */ "+G",
+        /* h   */ "+H",   /* i   */ "+I",   /* j   */ "+J",   /* k   */ "+K",
+        /* l   */ "+L",   /* m   */ "+M",   /* n   */ "+N",   /* o   */ "+O",
+        /* p   */ "+P",   /* q   */ "+Q",   /* r   */ "+R",   /* s   */ "+S",
+        /* t   */ "+T",   /* u   */ "+U",   /* v   */ "+V",   /* w   */ "+W",
+        /* x   */ "+X",   /* y   */ "+Y",   /* z   */ "+Z",   /* {   */ "%P",
+        /* |   */ "%Q",   /* }   */ "%R",   /* ~   */ "%S",   /* DEL */ "%T" 
+};
+
+
+/*===========================================*/
+/* Local function prototypes                 */
+/*===========================================*/
+
+static gchar      *code39_encode    (const gchar *data,
+                                     gboolean     checksum_flag);
+
+static lglBarcode *code39_vectorize (const gchar *code,
+                                     gdouble      w,
+                                     gdouble      h,
+                                     gboolean     text_flag,
+                                     gboolean     checksum_flag,
+                                     const gchar *data,
+                                     const gchar *string);
+
+
+/****************************************************************************/
+/* Generate list of lines that form the barcode for the given digits.       */
+/****************************************************************************/
+lglBarcode *
+lgl_barcode_code39_new (lglBarcodeType  type,
+                        gboolean        text_flag,
+                        gboolean        checksum_flag,
+                        gdouble         w,
+                        gdouble         h,
+                        const gchar    *data)
+{
+        gchar         *canon_data;
+        gchar         *display_data;
+        gchar         *code, *p;
+        lglBarcode    *bc;
+
+        if ( (type != LGL_BARCODE_TYPE_CODE39) &&
+             (type != LGL_BARCODE_TYPE_CODE39_EXT) )
+        {
+                g_message ("Invalid barcode type for CODE39 backend.");
+                return NULL;
+        }
+
+
+        /* Canonicalize data. */
+        if ( data[0] == '\0' )
+        {
+                return NULL;
+        }
+        if (type == LGL_BARCODE_TYPE_CODE39_EXT)
+        {
+                GString *canon_data_str;
+                GString *display_data_str;
+
+                canon_data_str = g_string_new ("");
+                display_data_str = g_string_new ("");
+                for ( p = (gchar *)data; *p != '\0'; p++ )
+                {
+                        canon_data_str = g_string_append (canon_data_str, ascii_map[(*p) & 0x7F]);
+                        display_data_str = g_string_append_c (display_data_str, (*p) & 0x7F);
+                }
+
+                canon_data   = g_string_free (canon_data_str, FALSE);
+                display_data = g_string_free (display_data_str, FALSE);
+        }
+        else
+        {
+                canon_data = g_ascii_strup (data, -1);
+                g_strcanon (canon_data, "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ-. $/+%", ' ');
+                display_data = g_strdup (canon_data);
+        }
+
+        /* First get code string */
+        code = code39_encode (canon_data, checksum_flag);
+        if (code == NULL) {
+                return NULL;
+        }
+
+        /* Now vectorize code string */
+        bc = code39_vectorize (code, w, h, text_flag, checksum_flag, canon_data, display_data);
+
+        g_free (canon_data);
+        g_free (display_data);
+        g_free (code);
+
+        return bc;
+}
+
+
+/*--------------------------------------------------------------------------*/
+/* PRIVATE.  Generate string of symbols, representing barcode.              */
+/*--------------------------------------------------------------------------*/
+static gchar *
+code39_encode (const gchar *data,
+               gboolean     checksum_flag)
+{
+        gchar         *p, c;
+        gint           i, sum;
+        GString       *code;
+
+
+        /* Left frame symbol */
+        code = g_string_new( frame_symbol );
+        code = g_string_append( code, "i" );
+
+        sum = 0;
+        for ( p=(gchar *)data; *p != 0; p++ )
+        {
+                c = toupper( *p );
+                for ( i = 0; symbols[i].c != 0; i++ )
+                {
+                        if ( c == symbols[i].c )
+                        {
+                                sum += i;
+                                code = g_string_append (code, symbols[i].sym);
+                                break;
+                        }
+                }
+                code = g_string_append (code, "i");
+        }
+
+        if ( checksum_flag )
+        {
+                code = g_string_append (code, symbols[sum % 43].sym);
+                code = g_string_append (code, "i");
+        }
+
+        /* Right frame bar */
+        code = g_string_append (code, frame_symbol);
+
+        return g_string_free (code, FALSE);
+}
+
+
+/*--------------------------------------------------------------------------*/
+/* Generate list of rectangles that form the barcode for the given digits.  */
+/*--------------------------------------------------------------------------*/
+static lglBarcode *
+code39_vectorize (const gchar   *code,
+                  gdouble        w,
+                  gdouble        h,
+                  gboolean       text_flag,
+                  gboolean       checksum_flag,
+                  const gchar   *data,
+                  const gchar   *string)
+{
+        gint         n_chars;
+        gdouble      min_l;
+        gdouble      scale;
+        gdouble      width, height;
+        gdouble      x_quiet;
+        lglBarcode  *bc;
+        gchar       *p;
+        gdouble      x1;
+        gchar       *string_plus_stars;
+
+        /* determine width and establish horizontal scale */
+        n_chars = strlen (data);
+        if (!checksum_flag)
+        {
+                min_l = (n_chars + 2)*(3*N + 6)*MIN_X + (n_chars + 1)*MIN_I;
+        }
+        else
+        {
+                min_l = (n_chars + 3)*(3*N + 6)*MIN_X + (n_chars + 2)*MIN_I;
+        }
+        
+        if ( w == 0 )
+        {
+                scale = 1.0;
+        }
+        else
+        {
+                scale = w / (min_l + 2*MIN_QUIET);
+
+                if ( scale < 1.0 )
+                {
+                        scale = 1.0;
+                }
+        }
+        width = min_l * scale;
+
+        /* determine height of barcode */
+        height = text_flag ? h - TEXT_AREA_HEIGHT : h;
+        height = MAX (height, MAX(0.15*width, MIN_HEIGHT));
+
+        /* determine horizontal quiet zone */
+        x_quiet = MAX ((10 * scale * MIN_X), MIN_QUIET);
+
+
+        bc = lgl_barcode_new ();
+
+        /* Now traverse the code string and create a list of rectangles */
+        x1 = x_quiet;
+        for ( p = (gchar *)code; *p != 0; p++ )
+        {
+
+                switch ( *p )
+                {
+
+                case 'i':
+                        /* Inter-character gap */
+                        x1 += scale * MIN_I;
+                        break;
+
+                case 'N':
+                        /* Narrow bar */
+                        lgl_barcode_add_box (bc, x1, 0.0, (scale * MIN_X - INK_BLEED), height);
+                        x1 += scale * MIN_X;
+                        break;
+
+                case 'W':
+                        /* Wide bar */
+                        lgl_barcode_add_box (bc, x1, 0.0, (scale * N * MIN_X - INK_BLEED), height);
+                        x1 += scale * N * MIN_X;
+                        break;
+
+                case 'n':
+                        /* Narrow space */
+                        x1 += scale * MIN_X;
+                        break;
+
+                case 'w':
+                        /* Wide space */
+                        x1 += scale * N * MIN_X;
+                        break;
+
+                default:
+                        g_message( "Invalid Code39 symbol, should not happen" );
+                        break;
+                }
+        }
+
+        if ( text_flag )
+        {
+                string_plus_stars = g_strdup_printf ("*%s*", string);
+                lgl_barcode_add_string (bc,
+                                        x_quiet + width/2, height + (TEXT_AREA_HEIGHT-TEXT_SIZE)/2,
+                                        TEXT_SIZE, string_plus_stars, strlen (string_plus_stars));
+                g_free (string_plus_stars);
+        }
+
+        bc->width  = width + 2*x_quiet;
+        bc->height = text_flag ? height + TEXT_AREA_HEIGHT : height;
+
+        return bc;
+}
+
+
+
+
+/*
+ * 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-onecode.h b/libglbarcode/lgl-barcode-code39.h
similarity index 60%
copy from src/bc-onecode.h
copy to libglbarcode/lgl-barcode-code39.h
index dec3e3b..dccaaae 100644
--- a/src/bc-onecode.h
+++ b/libglbarcode/lgl-barcode-code39.h
@@ -1,6 +1,6 @@
 /*
- *  bc-onecode.h
- *  Copyright (C) 2010  Jim Evins <evins snaught com>.
+ *  lgl-barcode-code39.h
+ *  Copyright (C) 2001-2010  Jim Evins <evins snaught com>.
  *
  *  This file is part of gLabels.
  *
@@ -18,23 +18,24 @@
  *  along with gLabels.  If not, see <http://www.gnu.org/licenses/>.
  */
 
-#ifndef __BC_ONECODE_H__
-#define __BC_ONECODE_H__
+#ifndef __LGL_BARCODE_CODE39_H__
+#define __LGL_BARCODE_CODE39_H__
 
-#include "bc.h"
+#include "lgl-barcode.h"
+#include "lgl-barcode-type.h"
 
 G_BEGIN_DECLS
 
-glBarcode *gl_barcode_onecode_new (const gchar    *id,
-				   gboolean        text_flag,
-				   gboolean        checksum_flag,
-				   gdouble         w,
-				   gdouble         h,
-				   const gchar    *digits);
+lglBarcode *lgl_barcode_code39_new (lglBarcodeType  type,
+                                    gboolean        text_flag,
+                                    gboolean        checksum_flag,
+                                    gdouble         w,
+                                    gdouble         h,
+                                    const gchar    *data);
 
 G_END_DECLS
 
-#endif /* __BC_ONECODE_H__ */
+#endif /* __LGL_BARCODE_CODE39_H__ */
 
 
 
diff --git a/libglbarcode/lgl-barcode-create.c b/libglbarcode/lgl-barcode-create.c
new file mode 100644
index 0000000..fe2dadc
--- /dev/null
+++ b/libglbarcode/lgl-barcode-create.c
@@ -0,0 +1,99 @@
+/*
+ *  lgl-barcode-create.c
+ *  Copyright (C) 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/>.
+ */
+
+#include <config.h>
+
+#include "lgl-barcode-create.h"
+
+#include "lgl-barcode-postnet.h"
+#include "lgl-barcode-onecode.h"
+#include "lgl-barcode-code39.h"
+
+
+/*===========================================*/
+/* Private macros and constants.             */
+/*===========================================*/
+
+
+/*===========================================*/
+/* Private types                             */
+/*===========================================*/
+
+typedef lglBarcode *(*BarcodeNewFunc) (lglBarcodeType  type,
+                                       gboolean        text_flag,
+                                       gboolean        checksum_flag,
+                                       gdouble         w,
+                                       gdouble         h,
+                                       const gchar    *data);
+
+
+/*===========================================*/
+/* Private globals                           */
+/*===========================================*/
+
+BarcodeNewFunc create_func[LGL_BARCODE_N_TYPES] = {
+
+        /* LGL_BARCODE_TYPE_POSTNET    */ lgl_barcode_postnet_new,
+        /* LGL_BARCODE_TYPE_POSTNET_5  */ lgl_barcode_postnet_new,
+        /* LGL_BARCODE_TYPE_POSTNET_9  */ lgl_barcode_postnet_new,
+        /* LGL_BARCODE_TYPE_POSTNET_11 */ lgl_barcode_postnet_new,
+        /* LGL_BARCODE_TYPE_CEPNET     */ lgl_barcode_postnet_new,
+
+        /* LGL_BARCODE_TYPE_ONECODE    */ lgl_barcode_onecode_new,
+
+        /* LGL_BARCODE_TYPE_CODE39     */ lgl_barcode_code39_new,
+        /* LGL_BARCODE_TYPE_CODE39_EXT */ lgl_barcode_code39_new,
+};
+
+/*===========================================*/
+/* Local function prototypes                 */
+/*===========================================*/
+
+
+/****************************************************************************/
+/* Lookup barcode type and create appropriate barcode.                      */
+/****************************************************************************/
+lglBarcode *
+lgl_barcode_create (lglBarcodeType     type,
+                    gboolean           text_flag,
+                    gboolean           checksum_flag,
+                    gdouble            w,
+                    gdouble            h,
+                    const gchar       *data)
+{
+        if ( (type < 0) || (type >= LGL_BARCODE_N_TYPES) )
+        {
+                g_message ("Invalid barcode type.");
+                return NULL;
+        }
+
+        return create_func[type] (type, text_flag, checksum_flag, w, h, data);
+}
+
+
+
+/*
+ * 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-onecode.h b/libglbarcode/lgl-barcode-create.h
similarity index 60%
copy from src/bc-onecode.h
copy to libglbarcode/lgl-barcode-create.h
index dec3e3b..61cb591 100644
--- a/src/bc-onecode.h
+++ b/libglbarcode/lgl-barcode-create.h
@@ -1,6 +1,6 @@
 /*
- *  bc-onecode.h
- *  Copyright (C) 2010  Jim Evins <evins snaught com>.
+ *  lgl-barcode-create.h
+ *  Copyright (C) 2001-2010  Jim Evins <evins snaught com>.
  *
  *  This file is part of gLabels.
  *
@@ -18,23 +18,27 @@
  *  along with gLabels.  If not, see <http://www.gnu.org/licenses/>.
  */
 
-#ifndef __BC_ONECODE_H__
-#define __BC_ONECODE_H__
+#ifndef __LGL_BARCODE_CREATE_H__
+#define __LGL_BARCODE_CREATE_H__
 
-#include "bc.h"
+#include <glib.h>
+
+#include "lgl-barcode.h"
+#include "lgl-barcode-type.h"
 
 G_BEGIN_DECLS
 
-glBarcode *gl_barcode_onecode_new (const gchar    *id,
-				   gboolean        text_flag,
-				   gboolean        checksum_flag,
-				   gdouble         w,
-				   gdouble         h,
-				   const gchar    *digits);
+
+lglBarcode  *lgl_barcode_create (lglBarcodeType     type,
+                                 gboolean           text_flag,
+                                 gboolean           checksum_flag,
+                                 gdouble            w,
+                                 gdouble            h,
+                                 const gchar       *data);
 
 G_END_DECLS
 
-#endif /* __BC_ONECODE_H__ */
+#endif /* __LGL_BARCODE_CREATE_H__ */
 
 
 
diff --git a/src/bc-onecode.c b/libglbarcode/lgl-barcode-onecode.c
similarity index 85%
rename from src/bc-onecode.c
rename to libglbarcode/lgl-barcode-onecode.c
index d62460a..ba06ec3 100644
--- a/src/bc-onecode.c
+++ b/libglbarcode/lgl-barcode-onecode.c
@@ -1,5 +1,5 @@
 /*
- *  bc-onecode.c
+ *  lgl-barcode-onecode.c
  *  Copyright (C) 2010  Jim Evins <evins snaught com>.
  *
  *  This file is part of gLabels.
@@ -25,15 +25,12 @@
 
 #include <config.h>
 
-#include "bc-onecode.h"
+#include "lgl-barcode-onecode.h"
 
 #include <glib.h>
 #include <ctype.h>
 #include <string.h>
 
-#include "debug.h"
-
-
 /*========================================================*/
 /* Private macros and constants.                          */
 /*========================================================*/
@@ -301,84 +298,59 @@ static guint character_table[] = {
 /*===========================================*/
 /* Local function prototypes                 */
 /*===========================================*/
-static gboolean  is_string_valid   (const gchar      *digits);
+static gboolean     is_string_valid    (const gchar      *data);
+
+static gchar       *onecode_encode     (const gchar      *data);
 
-static gchar    *onecode_code      (const gchar      *digits);
+static void         int104_mult_uint   (Int104           *x,
+                                        guint             y);
+static void         int104_add_uint    (Int104           *x,
+                                        guint             y);
+static void         int104_add_uint64  (Int104           *x,
+                                        guint64           y);
+static guint        int104_div_uint    (Int104           *x,
+                                        guint             y);
+#ifdef DEBUG
+static void         int104_print       (Int104           *x);
+#endif
 
-static void      int104_mult_uint  (Int104           *x,
-                                    guint             y);
-static void      int104_add_uint   (Int104           *x,
-                                    guint             y);
-static void      int104_add_uint64 (Int104           *x,
-                                    guint64           y);
-static guint     int104_div_uint   (Int104           *x,
-                                    guint             y);
-static void      int104_print      (Int104           *x);
+static unsigned short   USPS_MSB_Math_CRC11GenerateFrameCheckSequence( unsigned char *ByteArrayPtr );
 
-unsigned short   USPS_MSB_Math_CRC11GenerateFrameCheckSequence( unsigned char *ByteArrayPtr );
+static lglBarcode  *onecode_vectorize  (const gchar      *code);
 
 
 /****************************************************************************/
 /* Generate list of lines that form the barcode for the given digits.       */
 /****************************************************************************/
-glBarcode *
-gl_barcode_onecode_new (const gchar    *id,
-                        gboolean        text_flag,
-                        gboolean        checksum_flag,
-                        gdouble         w,
-                        gdouble         h,
-                        const gchar    *digits)
+lglBarcode *
+lgl_barcode_onecode_new (lglBarcodeType  type,
+                         gboolean        text_flag,
+                         gboolean        checksum_flag,
+                         gdouble         w,
+                         gdouble         h,
+                         const gchar    *data)
 {
-        gchar              *code, *p;
-        glBarcode          *gbc;
-        gdouble             x, y, length, width;
+        gchar              *code;
+        lglBarcode         *bc;
+
+        if ( type != LGL_BARCODE_TYPE_ONECODE )
+        {
+                g_message ("Invalid barcode type for ONECODE backend.");
+                return NULL;
+        }
 
         /* First get code string */
-        code = onecode_code (digits);
+        code = onecode_encode (data);
         if (code == NULL) {
                 return NULL;
         }
 
-        gbc = gl_barcode_new ();
-
-        /* Now traverse the code string and create a list of lines */
-        x = ONECODE_HORIZ_MARGIN;
-        for (p = code; *p != 0; p++) {
-                y = ONECODE_VERT_MARGIN;
-                switch ( *p )
-                {
-                case 'T':
-                        y      += ONECODE_TRACKER_OFFSET;
-                        length  = ONECODE_TRACKER_HEIGHT;
-                        break;
-                case 'D':
-                        y      += ONECODE_DESCENDER_OFFSET;
-                        length  = ONECODE_DESCENDER_HEIGHT;
-                        break;
-                case 'A':
-                        y      += ONECODE_ASCENDER_OFFSET;
-                        length  = ONECODE_ASCENDER_HEIGHT;
-                        break;
-                case 'F':
-                        y      += ONECODE_FULL_OFFSET;
-                        length  = ONECODE_FULL_HEIGHT;
-                        break;
-                default:
-                        break;
-                }
-                width = ONECODE_BAR_WIDTH;
-
-                gl_barcode_add_line (gbc, x, y, length, width);
-
-                x += ONECODE_BAR_PITCH;
-        }
+        /* Now vectorize encoded data. */
+        bc = onecode_vectorize (code);
 
         g_free (code);
 
-        gbc->width = x + ONECODE_HORIZ_MARGIN;
-        gbc->height = ONECODE_FULL_HEIGHT + 2 * ONECODE_VERT_MARGIN;
-
-        return gbc;
+        return bc;
 }
 
 
@@ -386,18 +358,17 @@ gl_barcode_onecode_new (const gchar    *id,
 /* PRIVATE.  Generate string of symbols, representing barcode.              */
 /*--------------------------------------------------------------------------*/
 static gchar *
-onecode_code (const gchar *digits)
+onecode_encode (const gchar *data)
 {
-        Int104   value = {0};
+        Int104   value = {{0}};
         gint     i;
         guint    crc11;
         guint    codeword[10];
         guint    character[10];
         gint     d, a;
         GString *code;
-        gchar   *ret;
 
-        if ( !is_string_valid (digits) )
+        if ( !is_string_valid (data) )
         {
                 return NULL;
         }
@@ -408,10 +379,10 @@ onecode_code (const gchar *digits)
         /*-----------------------------------------------------------*/
 
         /* Step 1.a -- Routing Code */
-        for ( i = 20; digits[i] != 0; i++ )
+        for ( i = 20; data[i] != 0; i++ )
         {
                 int104_mult_uint (&value, 10);
-                int104_add_uint  (&value, digits[i] - '0');
+                int104_add_uint  (&value, data[i] - '0');
         }
         switch ( i-20 )
         {
@@ -436,14 +407,14 @@ onecode_code (const gchar *digits)
 
         /* Step 1.b -- Tracking Code */
         int104_mult_uint (&value, 10);
-        int104_add_uint  (&value, digits[0] - '0');
+        int104_add_uint  (&value, data[0] - '0');
         int104_mult_uint (&value, 5);
-        int104_add_uint  (&value, digits[1] - '0');
+        int104_add_uint  (&value, data[1] - '0');
 
         for ( i = 2; i < 20; i++ )
         {
                 int104_mult_uint (&value, 10);
-                int104_add_uint  (&value, digits[i] - '0');
+                int104_add_uint  (&value, data[i] - '0');
         }
 
 
@@ -503,10 +474,7 @@ onecode_code (const gchar *digits)
         }
 
 
-        ret = g_strdup (code->str);
-        g_string_free (code, TRUE);
-
-        return ret;
+        return g_string_free (code, FALSE);
 }
 
 
@@ -514,16 +482,16 @@ onecode_code (const gchar *digits)
 /* Validate if string is of proper length & contains only valid characters. */
 /*--------------------------------------------------------------------------*/
 static gboolean
-is_string_valid (const gchar *digits)
+is_string_valid (const gchar *data)
 {
         gchar *p;
         gint   str_length;
 
-        if (!digits) {
+        if (!data) {
                 return FALSE;
         }
 
-        str_length = strlen (digits);
+        str_length = strlen (data);
         if ( (str_length != 20) &&
              (str_length != 25) &&
              (str_length != 29) &&
@@ -532,7 +500,7 @@ is_string_valid (const gchar *digits)
                 return FALSE;
         }
 
-        for ( p = (gchar *)digits; *p != 0; p++ )
+        for ( p = (gchar *)data; *p != 0; p++ )
         {
                 if (!g_ascii_isdigit (*p))
                 {
@@ -540,7 +508,7 @@ is_string_valid (const gchar *digits)
                 }
         }
 
-        if (digits[1] > '4')
+        if (data[1] > '4')
         {
                 return FALSE; /* Invalid Barcode Identifier. */
         }
@@ -638,6 +606,7 @@ int104_div_uint (Int104 *x,
 /*--------------------------------------------------------------------------*/
 /* Print hex representation of 104 bit integer.  (For debugging)            */
 /*--------------------------------------------------------------------------*/
+#ifdef DEBUG
 static void
 int104_print (Int104  *x)
 {
@@ -649,6 +618,7 @@ int104_print (Int104  *x)
         }
         g_print ("\n");
 }
+#endif
 
 
 /***************************************************************************
@@ -667,49 +637,101 @@ int104_print (Int104  *x)
 unsigned short
 USPS_MSB_Math_CRC11GenerateFrameCheckSequence( unsigned char *ByteArrayPtr )
 {
-	unsigned short  GeneratorPolynomial = 0x0F35;
-	unsigned short  FrameCheckSequence  = 0x07FF;
-	unsigned short  Data;
-	int             ByteIndex, Bit;
-
-	/* Do most significant byte skipping the 2 most significant bits */
-	Data = *ByteArrayPtr << 5;
-	ByteArrayPtr++;
-	for ( Bit = 2; Bit < 8; Bit++ )
-	{
-		if ( (FrameCheckSequence ^ Data) & 0x400 )
+        unsigned short  GeneratorPolynomial = 0x0F35;
+        unsigned short  FrameCheckSequence  = 0x07FF;
+        unsigned short  Data;
+        int             ByteIndex, Bit;
+
+        /* Do most significant byte skipping the 2 most significant bits */
+        Data = *ByteArrayPtr << 5;
+        ByteArrayPtr++;
+        for ( Bit = 2; Bit < 8; Bit++ )
+        {
+                if ( (FrameCheckSequence ^ Data) & 0x400 )
                 {
-			FrameCheckSequence = (FrameCheckSequence << 1) ^ GeneratorPolynomial;
+                        FrameCheckSequence = (FrameCheckSequence << 1) ^ GeneratorPolynomial;
                 }
-		else
+                else
                 {
-			FrameCheckSequence = (FrameCheckSequence << 1);
+                        FrameCheckSequence = (FrameCheckSequence << 1);
                 }
-		FrameCheckSequence &= 0x7FF;
-		Data <<= 1;
-	}
-
-	/* Do rest of the bytes */
-	for ( ByteIndex = 1; ByteIndex < 13; ByteIndex++ )
-	{
-		Data = *ByteArrayPtr << 3;
-		ByteArrayPtr++;
-		for ( Bit = 0; Bit < 8; Bit++ )
-		{
-			if ( (FrameCheckSequence ^ Data) & 0x0400 )
+                FrameCheckSequence &= 0x7FF;
+                Data <<= 1;
+        }
+
+        /* Do rest of the bytes */
+        for ( ByteIndex = 1; ByteIndex < 13; ByteIndex++ )
+        {
+                Data = *ByteArrayPtr << 3;
+                ByteArrayPtr++;
+                for ( Bit = 0; Bit < 8; Bit++ )
+                {
+                        if ( (FrameCheckSequence ^ Data) & 0x0400 )
                         {
-				FrameCheckSequence = (FrameCheckSequence << 1) ^ GeneratorPolynomial;
-			}
+                                FrameCheckSequence = (FrameCheckSequence << 1) ^ GeneratorPolynomial;
+                        }
                         else
                         {
-				FrameCheckSequence = (FrameCheckSequence << 1);
-			}
-			FrameCheckSequence &= 0x7FF;
-			Data <<= 1;
-		}
-	}
-
-	return FrameCheckSequence;
+                                FrameCheckSequence = (FrameCheckSequence << 1);
+                        }
+                        FrameCheckSequence &= 0x7FF;
+                        Data <<= 1;
+                }
+        }
+
+        return FrameCheckSequence;
+}
+
+
+/*--------------------------------------------------------------------------*/
+/* Vectorize encoded data.                                                  */
+/*--------------------------------------------------------------------------*/
+static lglBarcode *
+onecode_vectorize (const gchar  *code)
+{
+        lglBarcode         *bc;
+        gchar              *p;
+        gdouble             x, y, length, width;
+
+        bc = lgl_barcode_new ();
+
+        /* Now traverse the code string and create a list of lines */
+        x = ONECODE_HORIZ_MARGIN;
+        for (p = (gchar *)code; *p != 0; p++)
+        {
+                y = ONECODE_VERT_MARGIN;
+                switch ( *p )
+                {
+                case 'T':
+                        y      += ONECODE_TRACKER_OFFSET;
+                        length  = ONECODE_TRACKER_HEIGHT;
+                        break;
+                case 'D':
+                        y      += ONECODE_DESCENDER_OFFSET;
+                        length  = ONECODE_DESCENDER_HEIGHT;
+                        break;
+                case 'A':
+                        y      += ONECODE_ASCENDER_OFFSET;
+                        length  = ONECODE_ASCENDER_HEIGHT;
+                        break;
+                case 'F':
+                        y      += ONECODE_FULL_OFFSET;
+                        length  = ONECODE_FULL_HEIGHT;
+                        break;
+                default:
+                        break;
+                }
+                width = ONECODE_BAR_WIDTH;
+
+                lgl_barcode_add_box (bc, x, y, width, length);
+
+                x += ONECODE_BAR_PITCH;
+        }
+
+        bc->width = x + ONECODE_HORIZ_MARGIN;
+        bc->height = ONECODE_FULL_HEIGHT + 2 * ONECODE_VERT_MARGIN;
+
+        return bc;
 }
 
 
diff --git a/src/bc-onecode.h b/libglbarcode/lgl-barcode-onecode.h
similarity index 64%
copy from src/bc-onecode.h
copy to libglbarcode/lgl-barcode-onecode.h
index dec3e3b..f7465ee 100644
--- a/src/bc-onecode.h
+++ b/libglbarcode/lgl-barcode-onecode.h
@@ -1,5 +1,5 @@
 /*
- *  bc-onecode.h
+ *  lgl-barcode-onecode.h
  *  Copyright (C) 2010  Jim Evins <evins snaught com>.
  *
  *  This file is part of gLabels.
@@ -18,23 +18,24 @@
  *  along with gLabels.  If not, see <http://www.gnu.org/licenses/>.
  */
 
-#ifndef __BC_ONECODE_H__
-#define __BC_ONECODE_H__
+#ifndef __LGL_BARCODE_ONECODE_H__
+#define __LGL_BARCODE_ONECODE_H__
 
-#include "bc.h"
+#include "lgl-barcode.h"
+#include "lgl-barcode-type.h"
 
 G_BEGIN_DECLS
 
-glBarcode *gl_barcode_onecode_new (const gchar    *id,
-				   gboolean        text_flag,
-				   gboolean        checksum_flag,
-				   gdouble         w,
-				   gdouble         h,
-				   const gchar    *digits);
+lglBarcode *lgl_barcode_onecode_new (lglBarcodeType  type,
+                                     gboolean        text_flag,
+                                     gboolean        checksum_flag,
+                                     gdouble         w,
+                                     gdouble         h,
+                                     const gchar    *data);
 
 G_END_DECLS
 
-#endif /* __BC_ONECODE_H__ */
+#endif /* __LGL_BARCODE_ONECODE_H__ */
 
 
 
diff --git a/libglbarcode/lgl-barcode-postnet.c b/libglbarcode/lgl-barcode-postnet.c
new file mode 100644
index 0000000..96b4132
--- /dev/null
+++ b/libglbarcode/lgl-barcode-postnet.c
@@ -0,0 +1,272 @@
+/*
+ *  lgl-barcode-postnet.c
+ *  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/>.
+ */
+
+/*
+ * This module implements the POSTNET barcode specified in the USPS
+ * publication 25, Mar 2001.
+ */
+
+#include <config.h>
+
+#include "lgl-barcode-postnet.h"
+
+#include <glib.h>
+#include <ctype.h>
+
+
+/*========================================================*/
+/* Private macros and constants.                          */
+/*========================================================*/
+
+#define PTS_PER_INCH 72.0
+
+#define POSTNET_BAR_WIDTH      ( 0.02    * PTS_PER_INCH )
+#define POSTNET_FULLBAR_HEIGHT ( 0.125   * PTS_PER_INCH )
+#define POSTNET_HALFBAR_HEIGHT ( 0.05    * PTS_PER_INCH )
+#define POSTNET_BAR_PITCH      ( 0.04545 * PTS_PER_INCH )
+#define POSTNET_HORIZ_MARGIN   ( 0.125   * PTS_PER_INCH )
+#define POSTNET_VERT_MARGIN    ( 0.04    * PTS_PER_INCH )
+
+
+/*===========================================*/
+/* Private globals                           */
+/*===========================================*/
+static gchar *symbols[] = {
+        /* 0 */ "11000",
+        /* 1 */ "00011",
+        /* 2 */ "00101",
+        /* 3 */ "00110",
+        /* 4 */ "01001",
+        /* 5 */ "01010",
+        /* 6 */ "01100",
+        /* 7 */ "10001",
+        /* 8 */ "10010",
+        /* 9 */ "10100",
+};
+
+static gchar *frame_symbol = "1";
+
+
+/*===========================================*/
+/* Local function prototypes                 */
+/*===========================================*/
+static gchar       *postnet_encode    (const gchar *digits);
+
+static gboolean     is_length_valid   (const gchar *digits,
+                                       gint         n);
+
+static lglBarcode  *postnet_vectorize (const gchar *code);
+
+
+
+/****************************************************************************/
+/* Generate list of lines that form the barcode for the given digits.       */
+/****************************************************************************/
+lglBarcode *
+lgl_barcode_postnet_new (lglBarcodeType  type,
+                         gboolean        text_flag,
+                         gboolean        checksum_flag,
+                         gdouble         w,
+                         gdouble         h,
+                         const gchar    *data)
+{
+        gchar              *code;
+        lglBarcode         *bc;
+
+        /* Validate code length for all subtypes. */
+        switch (type)
+        {
+
+        case LGL_BARCODE_TYPE_POSTNET:
+                if (!is_length_valid (data, 5) &&
+                    !is_length_valid (data, 9) &&
+                    !is_length_valid (data, 11))
+                {
+                        return NULL;
+                }
+                break;
+
+        case LGL_BARCODE_TYPE_POSTNET_5:
+                if (!is_length_valid (data, 5))
+                {
+                        return NULL;
+                }
+                break;
+
+        case LGL_BARCODE_TYPE_POSTNET_9:
+                if (!is_length_valid (data, 9))
+                {
+                        return NULL;
+                }
+                break;
+
+        case LGL_BARCODE_TYPE_POSTNET_11:
+                if (!is_length_valid (data, 11))
+                {
+                        return NULL;
+                }
+                break;
+
+        case LGL_BARCODE_TYPE_CEPNET:
+                if (!is_length_valid (data, 8))
+                {
+                        return NULL;
+                }
+                break;
+
+        default:
+                g_message ("Invalid barcode type for POSTNET backend.");
+                return NULL;
+
+        }
+
+        /* First get code string */
+        code = postnet_encode (data);
+        if (code == NULL)
+        {
+                return NULL;
+        }
+
+        /* Now vectorize encoded data */
+        bc = postnet_vectorize (code);
+
+        g_free (code);
+
+        return bc;
+}
+
+
+/*--------------------------------------------------------------------------*/
+/* PRIVATE.  Generate string of symbols, representing barcode.              */
+/*--------------------------------------------------------------------------*/
+static gchar *
+postnet_encode (const gchar *data)
+{
+        gchar   *p;
+        gint     len;
+        gint     d, sum;
+        GString *code;
+
+        /* Left frame bar */
+        code = g_string_new (frame_symbol);
+
+        sum = 0;
+        for (p = (gchar *)data, len = 0; (*p != 0) && (len < 11); p++)
+        {
+                if (g_ascii_isdigit (*p))
+                {
+                        /* Only translate valid characters (0-9) */
+                        d = (*p) - '0';
+                        sum += d;
+                        code = g_string_append (code, symbols[d]);
+                        len++;
+                }
+        }
+
+        /* Create correction character */
+        d = (10 - (sum % 10)) % 10;
+        code = g_string_append (code, symbols[d]);
+
+        /* Right frame bar */
+        code = g_string_append (code, frame_symbol);
+
+        return g_string_free (code, FALSE);
+}
+
+
+/*--------------------------------------------------------------------------*/
+/* PRIVATE.  Validate specific length of string (for subtypes).             */
+/*--------------------------------------------------------------------------*/
+static gboolean
+is_length_valid (const gchar *data,
+                 gint         n)
+{
+        gchar *p;
+        gint   i;
+
+        if (!data)
+        {
+                return FALSE;
+        }
+
+        for (p = (gchar *)data, i=0; *p != 0; p++)
+        {
+                if (g_ascii_isdigit (*p))
+                {
+                        i++;
+                }
+        }
+
+        return (i == n);
+}
+
+
+/*--------------------------------------------------------------------------*/
+/* PRIVATE.  Vectorize encoded barcode.                                     */
+/*--------------------------------------------------------------------------*/
+static lglBarcode *
+postnet_vectorize (const gchar *code)
+{
+        lglBarcode         *bc;
+        gchar              *p;
+        gdouble             x, y, length, width;
+
+        bc = lgl_barcode_new ();
+
+        /* Now traverse the code string and create a list of lines */
+        x = POSTNET_HORIZ_MARGIN;
+        for (p = (gchar *)code; *p != 0; p++)
+        {
+                y = POSTNET_VERT_MARGIN;
+                switch (*p)
+                {
+                case '0':
+                        y += POSTNET_FULLBAR_HEIGHT - POSTNET_HALFBAR_HEIGHT;
+                        length = POSTNET_HALFBAR_HEIGHT;
+                        break;
+                case '1':
+                        length = POSTNET_FULLBAR_HEIGHT;
+                        break;
+                default:
+                        break;
+                }
+                width = POSTNET_BAR_WIDTH;
+
+                lgl_barcode_add_box (bc, x, y, width, length);
+
+                x += POSTNET_BAR_PITCH;
+        }
+
+        bc->width = x + POSTNET_HORIZ_MARGIN;
+        bc->height = POSTNET_FULLBAR_HEIGHT + 2 * POSTNET_VERT_MARGIN;
+
+        return bc;
+}
+
+
+
+/*
+ * 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-onecode.h b/libglbarcode/lgl-barcode-postnet.h
similarity index 60%
copy from src/bc-onecode.h
copy to libglbarcode/lgl-barcode-postnet.h
index dec3e3b..3d08477 100644
--- a/src/bc-onecode.h
+++ b/libglbarcode/lgl-barcode-postnet.h
@@ -1,6 +1,6 @@
 /*
- *  bc-onecode.h
- *  Copyright (C) 2010  Jim Evins <evins snaught com>.
+ *  lgl-barcode-postnet.h
+ *  Copyright (C) 2001-2010  Jim Evins <evins snaught com>.
  *
  *  This file is part of gLabels.
  *
@@ -18,23 +18,24 @@
  *  along with gLabels.  If not, see <http://www.gnu.org/licenses/>.
  */
 
-#ifndef __BC_ONECODE_H__
-#define __BC_ONECODE_H__
+#ifndef __LGL_BARCODE_POSTNET_H__
+#define __LGL_BARCODE_POSTNET_H__
 
-#include "bc.h"
+#include "lgl-barcode.h"
+#include "lgl-barcode-type.h"
 
 G_BEGIN_DECLS
 
-glBarcode *gl_barcode_onecode_new (const gchar    *id,
-				   gboolean        text_flag,
-				   gboolean        checksum_flag,
-				   gdouble         w,
-				   gdouble         h,
-				   const gchar    *digits);
+lglBarcode *lgl_barcode_postnet_new (lglBarcodeType  type,
+                                     gboolean        text_flag,
+                                     gboolean        checksum_flag,
+                                     gdouble         w,
+                                     gdouble         h,
+                                     const gchar    *data);
 
 G_END_DECLS
 
-#endif /* __BC_ONECODE_H__ */
+#endif /* __LGL_BARCODE_POSTNET_H__ */
 
 
 
diff --git a/libglbarcode/lgl-barcode-render-to-cairo.c b/libglbarcode/lgl-barcode-render-to-cairo.c
new file mode 100644
index 0000000..6cb84b3
--- /dev/null
+++ b/libglbarcode/lgl-barcode-render-to-cairo.c
@@ -0,0 +1,195 @@
+/*
+ *  lgl-barcode-render-to-cairo.c
+ *  Copyright (C) 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/>.
+ */
+
+#include <config.h>
+
+#include "lgl-barcode-render-to-cairo.h"
+
+#include <pango/pangocairo.h>
+#include <math.h>
+
+
+/*===========================================*/
+/* Private macros and constants.             */
+/*===========================================*/
+
+#define FONT_SCALE (72.0/96.0)
+#define BARCODE_FONT_FAMILY      "Sans"
+#define BARCODE_FONT_WEIGHT      PANGO_WEIGHT_NORMAL
+
+
+/*===========================================*/
+/* Private types                             */
+/*===========================================*/
+
+
+/*===========================================*/
+/* Private globals                           */
+/*===========================================*/
+
+
+/*===========================================*/
+/* Local function prototypes                 */
+/*===========================================*/
+
+
+/****************************************************************************/
+/* Render barcode to cairo context.                                         */
+/****************************************************************************/
+void
+lgl_barcode_render_to_cairo (const lglBarcode  *bc,
+                             cairo_t           *cr)
+{
+        GList                  *p;
+
+        lglBarcodeShape        *shape;
+        lglBarcodeShapeLine    *line;
+        lglBarcodeShapeBox     *box;
+        lglBarcodeShapeChar    *bchar;
+        lglBarcodeShapeString  *bstring;
+        lglBarcodeShapeRing    *ring;
+        lglBarcodeShapeHexagon *hexagon;
+
+        PangoLayout            *layout;
+        PangoFontDescription   *desc;
+        gchar                  *cstring;
+        gdouble                 x_offset, y_offset;
+        gint                    iw, ih;
+        gdouble                 layout_width;
+
+
+        for (p = bc->shapes; p != NULL; p = p->next) {
+
+                shape = (lglBarcodeShape *)p->data;
+
+                switch (shape->type)
+                {
+
+                case LGL_BARCODE_SHAPE_LINE:
+                        line = (lglBarcodeShapeLine *) shape;
+
+                        cairo_move_to (cr, line->x, line->y);
+                        cairo_line_to (cr, line->x, line->y + line->length);
+                        cairo_set_line_width (cr, line->width);
+                        cairo_stroke (cr);
+
+                        break;
+
+                case LGL_BARCODE_SHAPE_BOX:
+                        box = (lglBarcodeShapeBox *) shape;
+
+                        cairo_rectangle (cr, box->x, box->y, box->width, box->height);
+                        cairo_fill (cr);
+
+                        break;
+
+                case LGL_BARCODE_SHAPE_CHAR:
+                        bchar = (lglBarcodeShapeChar *) shape;
+
+                        layout = pango_cairo_create_layout (cr);
+
+                        desc = pango_font_description_new ();
+                        pango_font_description_set_family (desc, BARCODE_FONT_FAMILY);
+                        pango_font_description_set_size   (desc, bchar->fsize * PANGO_SCALE * FONT_SCALE);
+                        pango_layout_set_font_description (layout, desc);
+                        pango_font_description_free       (desc);
+
+                        cstring = g_strdup_printf ("%c", bchar->c);
+                        pango_layout_set_text (layout, cstring, -1);
+                        g_free (cstring);
+
+                        y_offset = 0.2 * bchar->fsize;
+
+                        cairo_move_to (cr, bchar->x, bchar->y-y_offset);
+                        pango_cairo_show_layout (cr, layout);
+
+                        g_object_unref (layout);
+
+                        break;
+
+                case LGL_BARCODE_SHAPE_STRING:
+                        bstring = (lglBarcodeShapeString *) shape;
+
+                        layout = pango_cairo_create_layout (cr);
+
+                        desc = pango_font_description_new ();
+                        pango_font_description_set_family (desc, BARCODE_FONT_FAMILY);
+                        pango_font_description_set_size   (desc, bstring->fsize * PANGO_SCALE * FONT_SCALE);
+                        pango_layout_set_font_description (layout, desc);
+                        pango_font_description_free       (desc);
+
+                        pango_layout_set_text (layout, bstring->string, -1);
+
+                        pango_layout_get_size (layout, &iw, &ih);
+                        layout_width = (gdouble)iw / (gdouble)PANGO_SCALE;
+
+                        x_offset = layout_width / 2.0;
+                        y_offset = 0.2 * bstring->fsize;
+
+                        cairo_move_to (cr, (bstring->x - x_offset), (bstring->y - y_offset));
+                        pango_cairo_show_layout (cr, layout);
+
+                        g_object_unref (layout);
+
+                        break;
+
+                case LGL_BARCODE_SHAPE_RING:
+                        ring = (lglBarcodeShapeRing *) shape;
+
+                        cairo_arc (cr, ring->x, ring->y, ring->radius, 0.0, 2 * M_PI);
+                        cairo_set_line_width (cr, ring->line_width);
+                        cairo_stroke (cr);
+
+                        break;
+
+                case LGL_BARCODE_SHAPE_HEXAGON:
+                        hexagon = (lglBarcodeShapeHexagon *) shape;
+
+                        cairo_move_to (cr, hexagon->x, hexagon->y);
+                        cairo_line_to (cr, hexagon->x + 0.433*hexagon->height, hexagon->y + 0.25*hexagon->height);
+                        cairo_line_to (cr, hexagon->x + 0.433*hexagon->height, hexagon->y + 0.75*hexagon->height);
+                        cairo_line_to (cr, hexagon->x,                         hexagon->y +      hexagon->height);
+                        cairo_line_to (cr, hexagon->x - 0.433*hexagon->height, hexagon->y + 0.75*hexagon->height);
+                        cairo_line_to (cr, hexagon->x - 0.433*hexagon->height, hexagon->y + 0.25*hexagon->height);
+                        cairo_close_path (cr);
+                        cairo_fill (cr);
+
+                        break;
+
+                default:
+                        g_assert_not_reached ();
+                        break;
+
+                }
+
+        }
+
+}
+
+
+
+/*
+ * 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-onecode.h b/libglbarcode/lgl-barcode-render-to-cairo.h
similarity index 75%
copy from src/bc-onecode.h
copy to libglbarcode/lgl-barcode-render-to-cairo.h
index dec3e3b..3ad67ad 100644
--- a/src/bc-onecode.h
+++ b/libglbarcode/lgl-barcode-render-to-cairo.h
@@ -1,5 +1,5 @@
 /*
- *  bc-onecode.h
+ *  lgl-barcode-render-to-cairo.h
  *  Copyright (C) 2010  Jim Evins <evins snaught com>.
  *
  *  This file is part of gLabels.
@@ -18,23 +18,20 @@
  *  along with gLabels.  If not, see <http://www.gnu.org/licenses/>.
  */
 
-#ifndef __BC_ONECODE_H__
-#define __BC_ONECODE_H__
+#ifndef __LGL_RENDER_TO_CAIRO_H__
+#define __LGL_RENDER_TO_CAIRO_H__
 
-#include "bc.h"
+#include "lgl-barcode.h"
+#include <cairo.h>
 
 G_BEGIN_DECLS
 
-glBarcode *gl_barcode_onecode_new (const gchar    *id,
-				   gboolean        text_flag,
-				   gboolean        checksum_flag,
-				   gdouble         w,
-				   gdouble         h,
-				   const gchar    *digits);
+void  lgl_barcode_render_to_cairo (const lglBarcode *bc,
+                                   cairo_t          *cr);
 
 G_END_DECLS
 
-#endif /* __BC_ONECODE_H__ */
+#endif /* __LGL_RENDER_TO_CAIRO_H__ */
 
 
 
diff --git a/src/bc-onecode.h b/libglbarcode/lgl-barcode-type.h
similarity index 63%
rename from src/bc-onecode.h
rename to libglbarcode/lgl-barcode-type.h
index dec3e3b..43634d7 100644
--- a/src/bc-onecode.h
+++ b/libglbarcode/lgl-barcode-type.h
@@ -1,6 +1,6 @@
 /*
- *  bc-onecode.h
- *  Copyright (C) 2010  Jim Evins <evins snaught com>.
+ *  lgl-barcode-type.h
+ *  Copyright (C) 2001-2010  Jim Evins <evins snaught com>.
  *
  *  This file is part of gLabels.
  *
@@ -18,23 +18,33 @@
  *  along with gLabels.  If not, see <http://www.gnu.org/licenses/>.
  */
 
-#ifndef __BC_ONECODE_H__
-#define __BC_ONECODE_H__
+#ifndef __LGL_BARCODE_TYPE_H__
+#define __LGL_BARCODE_TYPE_H__
 
-#include "bc.h"
+#include <glib.h>
 
 G_BEGIN_DECLS
 
-glBarcode *gl_barcode_onecode_new (const gchar    *id,
-				   gboolean        text_flag,
-				   gboolean        checksum_flag,
-				   gdouble         w,
-				   gdouble         h,
-				   const gchar    *digits);
+
+typedef enum {
+
+        LGL_BARCODE_TYPE_POSTNET,
+        LGL_BARCODE_TYPE_POSTNET_5,
+        LGL_BARCODE_TYPE_POSTNET_9,
+        LGL_BARCODE_TYPE_POSTNET_11,
+        LGL_BARCODE_TYPE_CEPNET,
+        LGL_BARCODE_TYPE_ONECODE,
+        LGL_BARCODE_TYPE_CODE39,
+        LGL_BARCODE_TYPE_CODE39_EXT,
+
+        LGL_BARCODE_N_TYPES
+
+} lglBarcodeType;
+
 
 G_END_DECLS
 
-#endif /* __BC_ONECODE_H__ */
+#endif /* __LGL_BARCODE_TYPE_H__ */
 
 
 
diff --git a/libglbarcode/lgl-barcode.c b/libglbarcode/lgl-barcode.c
new file mode 100644
index 0000000..25409d8
--- /dev/null
+++ b/libglbarcode/lgl-barcode.c
@@ -0,0 +1,257 @@
+/*
+ *  lgl-barcode.c
+ *  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/>.
+ */
+
+#include <config.h>
+
+#include "lgl-barcode.h"
+
+
+/*========================================================*/
+/* Private macros and constants.                          */
+/*========================================================*/
+
+
+/*========================================================*/
+/* Private types.                                         */
+/*========================================================*/
+
+
+/*========================================================*/
+/* Private globals.                                       */
+/*========================================================*/
+
+
+/*========================================================*/
+/* Private function prototypes.                           */
+/*========================================================*/
+
+static void lgl_barcode_add_shape        (lglBarcode      *bc,
+                                          lglBarcodeShape *shape);
+
+static void lgl_barcode_shape_free       (lglBarcodeShape *shape);
+
+
+/*****************************************************************************/
+/* Allocate new empty lglBarcode structure.                                  */
+/*****************************************************************************/
+lglBarcode *
+lgl_barcode_new (void)
+{
+        return g_new0 (lglBarcode, 1);
+}
+
+
+/*****************************************************************************/
+/* Free previously created barcode.                                          */
+/*****************************************************************************/
+void
+lgl_barcode_free (lglBarcode *bc)
+{
+        GList *p;
+
+        if (bc != NULL)
+        {
+
+                for (p = bc->shapes; p != NULL; p = p->next)
+                {
+                        lgl_barcode_shape_free ((lglBarcodeShape *)p->data);
+                }
+                g_list_free (bc->shapes);
+
+                g_free (bc);
+
+        }
+}
+
+
+/*****************************************************************************/
+/* Add a line.                                                               */
+/*****************************************************************************/
+void
+lgl_barcode_add_line (lglBarcode      *bc,
+                      gdouble          x,
+                      gdouble          y,
+                      gdouble          length,
+                      gdouble          width)
+{
+        lglBarcodeShapeLine *line_shape = g_new0 (lglBarcodeShapeLine, 1);
+        line_shape->type = LGL_BARCODE_SHAPE_LINE;
+
+        line_shape->x      = x;
+        line_shape->y      = y;
+        line_shape->length = length;
+        line_shape->width  = width;
+
+        lgl_barcode_add_shape (bc, (lglBarcodeShape *)line_shape);
+}
+
+
+/*****************************************************************************/
+/* Add box.                                                                  */
+/*****************************************************************************/
+void
+lgl_barcode_add_box (lglBarcode      *bc,
+                     gdouble          x,
+                     gdouble          y,
+                     gdouble          width,
+                     gdouble          height)
+{
+        lglBarcodeShapeBox *box_shape = g_new0 (lglBarcodeShapeBox, 1);
+        box_shape->type = LGL_BARCODE_SHAPE_BOX;
+
+        box_shape->x      = x;
+        box_shape->y      = y;
+        box_shape->width  = width;
+        box_shape->height = height;
+
+        lgl_barcode_add_shape (bc, (lglBarcodeShape *)box_shape);
+}
+
+
+/*****************************************************************************/
+/* Add character.                                                            */
+/*****************************************************************************/
+void
+lgl_barcode_add_char (lglBarcode      *bc,
+                      gdouble          x,
+                      gdouble          y,
+                      gdouble          fsize,
+                      gchar            c)
+{
+        lglBarcodeShapeChar *char_shape = g_new0 (lglBarcodeShapeChar, 1);
+        char_shape->type = LGL_BARCODE_SHAPE_CHAR;
+
+        char_shape->x      = x;
+        char_shape->y      = y;
+        char_shape->fsize  = fsize;
+        char_shape->c      = c;
+
+        lgl_barcode_add_shape (bc, (lglBarcodeShape *)char_shape);
+}
+
+
+/*****************************************************************************/
+/* Add string.                                                               */
+/*****************************************************************************/
+void
+lgl_barcode_add_string (lglBarcode      *bc,
+                        gdouble          x,
+                        gdouble          y,
+                        gdouble          fsize,
+                        gchar           *string,
+                        gsize            length)
+{
+        lglBarcodeShapeString *string_shape = g_new0 (lglBarcodeShapeString, 1);
+        string_shape->type = LGL_BARCODE_SHAPE_STRING;
+
+        string_shape->x      = x;
+        string_shape->y      = y;
+        string_shape->fsize  = fsize;
+        string_shape->string = g_strndup(string, length);
+
+        lgl_barcode_add_shape (bc, (lglBarcodeShape *)string_shape);
+}
+
+/*****************************************************************************/
+/* Add ring.                                                                 */
+/*****************************************************************************/
+void
+lgl_barcode_add_ring (lglBarcode      *bc,
+                      gdouble          x,
+                      gdouble          y,
+                      gdouble          radius,
+                      gdouble          line_width)
+{
+        lglBarcodeShapeRing *ring_shape = g_new0 (lglBarcodeShapeRing, 1);
+        ring_shape->type = LGL_BARCODE_SHAPE_RING;
+
+        ring_shape->x          = x;
+        ring_shape->y          = y;
+        ring_shape->radius     = radius;
+        ring_shape->line_width = line_width;
+
+        lgl_barcode_add_shape (bc, (lglBarcodeShape *)ring_shape);
+}
+
+/*****************************************************************************/
+/* Add hexagon.                                                              */
+/*****************************************************************************/
+void
+lgl_barcode_add_hexagon (lglBarcode      *bc,
+                         gdouble          x,
+                         gdouble          y,
+                         gdouble          height)
+{
+        lglBarcodeShapeHexagon *hexagon_shape = g_new0 (lglBarcodeShapeHexagon, 1);
+        hexagon_shape->type = LGL_BARCODE_SHAPE_HEXAGON;
+
+        hexagon_shape->x      = x;
+        hexagon_shape->y      = y;
+        hexagon_shape->height = height;
+
+        lgl_barcode_add_shape (bc, (lglBarcodeShape *)hexagon_shape);
+}
+
+
+/*****************************************************************************/
+/* Add shape to barcode.                                                     */
+/*****************************************************************************/
+static void
+lgl_barcode_add_shape (lglBarcode      *bc,
+                       lglBarcodeShape *shape)
+{
+        g_return_if_fail (bc);
+        g_return_if_fail (shape);
+
+        bc->shapes = g_list_prepend (bc->shapes, shape);
+}
+
+
+/*****************************************************************************/
+/* Free a shape primitive.                                                   */
+/*****************************************************************************/
+static void
+lgl_barcode_shape_free (lglBarcodeShape *shape)
+{
+        switch (shape->type)
+        {
+
+        case LGL_BARCODE_SHAPE_STRING:
+                g_free (shape->string.string);
+                break;
+
+        default:
+                break;
+        }
+
+        g_free (shape);
+}
+
+
+
+
+/*
+ * 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/libglbarcode/lgl-barcode.h b/libglbarcode/lgl-barcode.h
new file mode 100644
index 0000000..f7f9a07
--- /dev/null
+++ b/libglbarcode/lgl-barcode.h
@@ -0,0 +1,317 @@
+/*
+ *  lgl-barcode.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 __LGL_BARCODE_H__
+#define __LGL_BARCODE_H__
+
+#include <glib.h>
+
+G_BEGIN_DECLS
+
+
+/********************************/
+/* Barcode Intermediate Format. */
+/********************************/
+
+typedef struct {
+
+        gdouble  width;
+        gdouble  height;
+
+        GList   *shapes;    /* List of lglBarcodeShape drawing primitives */
+
+} lglBarcode;
+
+
+/********************************/
+/* Barcode Construction.        */
+/********************************/
+
+lglBarcode      *lgl_barcode_new              (void);
+
+void             lgl_barcode_free             (lglBarcode     *bc);
+
+void             lgl_barcode_add_line         (lglBarcode     *bc,
+                                               gdouble         x,
+                                               gdouble         y,
+                                               gdouble         length,
+                                               gdouble         width);
+
+void             lgl_barcode_add_box          (lglBarcode     *bc,
+                                               gdouble         x,
+                                               gdouble         y,
+                                               gdouble         width,
+                                               gdouble         height);
+
+void             lgl_barcode_add_char         (lglBarcode     *bc,
+                                               gdouble         x,
+                                               gdouble         y,
+                                               gdouble         fsize,
+                                               gchar           c);
+
+void             lgl_barcode_add_string       (lglBarcode     *bc,
+                                               gdouble         x,
+                                               gdouble         y,
+                                               gdouble         fsize,
+                                               gchar          *string,
+                                               gsize           length);
+
+void             lgl_barcode_add_ring         (lglBarcode     *bc,
+                                               gdouble         x,
+                                               gdouble         y,
+                                               gdouble         radius,
+                                               gdouble         line_width);
+
+void             lgl_barcode_add_hexagon      (lglBarcode     *bc,
+                                               gdouble         x,
+                                               gdouble         y,
+                                               gdouble         height);
+
+/*******************************/
+/* Barcode Drawing Primitives. */
+/*******************************/
+
+typedef enum {
+        LGL_BARCODE_SHAPE_LINE,
+        LGL_BARCODE_SHAPE_BOX,
+        LGL_BARCODE_SHAPE_CHAR,
+        LGL_BARCODE_SHAPE_STRING,
+        LGL_BARCODE_SHAPE_RING,
+        LGL_BARCODE_SHAPE_HEXAGON,
+} lglBarcodeShapeType;
+
+typedef struct {
+
+        /* Begin Common Fields */
+        lglBarcodeShapeType  type;
+        gdouble              x;
+        gdouble              y;
+        /* End Common Fields */
+
+} lglBarcodeShapeAny;
+
+/*
+ * lglBarcodeShapeLine:
+ *
+ * @ =  origin (x,y) from top left corner of barcode
+ *
+ *              +-- --+
+ *              |     |
+ *              |     |
+ *              |     |
+ *              |     | length
+ *              |     |
+ *              |     |
+ *              |     |
+ *              +-----+
+ *               width
+ */
+typedef struct {
+
+        /* Begin Common Fields */
+        lglBarcodeShapeType  type; /* Always LGL_BARCODE_SHAPE_LINE. */
+        gdouble              x;
+        gdouble              y;
+        /* End Common Fields */
+
+        gdouble              length;
+        gdouble              width;
+
+} lglBarcodeShapeLine;
+
+/*
+ * lglBarcodeShapeBox:
+ *
+ * @ =  origin (x,y) from top left corner of barcode
+ *
+ *              @---------+
+ *              |         |
+ *              |         |
+ *              |         |
+ *              |         | height
+ *              |         |
+ *              |         |
+ *              |         |
+ *              +---------+
+ *                 width
+ */
+typedef struct {
+
+        /* Begin Common Fields */
+        lglBarcodeShapeType  type; /* Always LGL_BARCODE_SHAPE_BOX. */
+        gdouble              x;
+        gdouble              y;
+        /* End Common Fields */
+
+        gdouble              width;
+        gdouble              height;
+
+} lglBarcodeShapeBox;
+
+/*
+ * lglBarcodeShapeChar:
+ *
+ * @ =  origin (x,y) from top left corner of barcode
+ *
+ *              ____ ------------
+ *             /    \           ^
+ *            /  /\  \          |
+ *           /  /__\  \         |
+ *          /  ______  \        | ~fsize
+ *         /  /      \  \       |
+ *        /__/        \__\      |
+ *                              v
+ *       @ ----------------------
+ */
+typedef struct {
+
+        /* Begin Common Fields */
+        lglBarcodeShapeType  type; /* Always LGL_BARCODE_SHAPE_CHAR. */
+        gdouble              x;
+        gdouble              y;
+        /* End Common Fields */
+
+        gdouble              fsize;
+        gchar                c;
+
+} lglBarcodeShapeChar;
+
+/*
+ * lglBarcodeShapeString:
+ *
+ * @ =  origin (x,y) from top left corner of barcode
+ *
+ *              ____        _  ------------------
+ *             /    \      | |                  ^
+ *            /  /\  \     | |                  |
+ *           /  /__\  \    | |___     ____      |
+ *          /  ______  \   | ._  \   /  __|     | ~fsize
+ *         /  /      \  \  | |_)  | |  (__      |
+ *        /__/        \__\ |_.___/   \____|     |
+ *                                              v
+ *                           @ ------------------
+ *                           x = horizontal center
+ */
+typedef struct {
+
+        /* Begin Common Fields */
+        lglBarcodeShapeType  type; /* Always LGL_BARCODE_SHAPE_STRING. */
+        gdouble              x;
+        gdouble              y;
+        /* End Common Fields */
+
+        gdouble              fsize;
+        gchar               *string;
+
+} lglBarcodeShapeString;
+
+/*
+ * lglBarcodeShapeRing:
+ *
+ * @ = origin (x,y) is centre of circle
+ *
+ *                v  line_width
+ *           _.-""""-._
+ *         .'   ____   `.
+ *        /   .'  ^ `.   \
+ *       |   /        \   |
+ *       |   |    @---|---|------
+ *       |   \        /   |     ^
+ *        \   `.____.'   /      | radius
+ *         `._    ...._.'.......|
+ *            `-....-'
+ */
+
+typedef struct {
+
+        /* Begin Common Fields */
+        lglBarcodeShapeType  type; /* Always LGL_BARCODE_SHAPE_RING. */
+        gdouble              x;
+        gdouble              y;
+        /* End Common Fields */
+
+        gdouble              radius;
+        gdouble              line_width;
+
+} lglBarcodeShapeRing;
+
+/*
+ * lglBarcodeShapeHexagon;
+ *
+ * @ = origin (x,y) is top of hexagon
+ *
+ *                  @ ------------------
+ *              _-"   "-_              ^
+ *          _-"           "-_          |
+ *       +"                   "+       |
+ *       |                     |       |
+ *       |                     |       |
+ *       |                     |       | height
+ *       |                     |       |
+ *       |                     |       |
+ *       +_                   _+       |
+ *         "-_             _-"         |
+ *            "-_       _-"            |
+ *               "-_ _-"               v
+ *                  " ------------------
+ *
+ */
+
+typedef struct {
+
+        /* Begin Common Fields */
+        lglBarcodeShapeType  type; /* Always LGL_BARCODE_SHAPE_HEXAGON. */
+        gdouble              x;
+        gdouble              y;
+        /* End Common Fields */
+
+        gdouble              height;
+
+} lglBarcodeShapeHexagon;
+
+typedef union {
+
+        lglBarcodeShapeType    type;
+        lglBarcodeShapeAny     any;
+
+        lglBarcodeShapeLine    line;
+        lglBarcodeShapeBox     box;
+        lglBarcodeShapeChar    bchar;
+        lglBarcodeShapeString  string;
+        lglBarcodeShapeRing    ring;
+        lglBarcodeShapeHexagon hexagon;
+
+} lglBarcodeShape;
+
+
+G_END_DECLS
+
+#endif /* __LGL_BARCODE_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/libglbarcode/libglbarcode-3.0.pc.in b/libglbarcode/libglbarcode-3.0.pc.in
new file mode 100644
index 0000000..bdcbf6d
--- /dev/null
+++ b/libglbarcode/libglbarcode-3.0.pc.in
@@ -0,0 +1,12 @@
+prefix= prefix@
+exec_prefix= exec_prefix@
+libdir= libdir@
+includedir= includedir@
+
+Name: LIBGLBARCODE
+Description: GLabels Built-In Barcode Library
+Requires: glib-2.0 cairo pango
+Version: @VERSION@
+Libs: -L${libdir} -lglbarcode-3.0
+Cflags: -I${includedir}/@LIBGLBARCODE_BRANCH@
+
diff --git a/src/bc-postnet.h b/libglbarcode/libglbarcode.h
similarity index 67%
copy from src/bc-postnet.h
copy to libglbarcode/libglbarcode.h
index 0945670..bad41ee 100644
--- a/src/bc-postnet.h
+++ b/libglbarcode/libglbarcode.h
@@ -1,6 +1,6 @@
 /*
- *  bc-postnet.h
- *  Copyright (C) 2001-2009  Jim Evins <evins snaught com>.
+ *  libglbarcode.h
+ *  Copyright (C) 2010  Jim Evins <evins snaught com>.
  *
  *  This file is part of gLabels.
  *
@@ -18,23 +18,21 @@
  *  along with gLabels.  If not, see <http://www.gnu.org/licenses/>.
  */
 
-#ifndef __BC_POSTNET_H__
-#define __BC_POSTNET_H__
+#ifndef __LIBGLBARCODE_H__
+#define __LIBGLBARCODE_H__
 
-#include "bc.h"
 
-G_BEGIN_DECLS
+#include <libglbarcode/lgl-barcode.h>
+#include <libglbarcode/lgl-barcode-type.h>
+#include <libglbarcode/lgl-barcode-create.h>
 
-glBarcode *gl_barcode_postnet_new (const gchar    *id,
-				   gboolean        text_flag,
-				   gboolean        checksum_flag,
-				   gdouble         w,
-				   gdouble         h,
-				   const gchar    *digits);
+#include <libglbarcode/lgl-barcode-render-to-cairo.h>
 
-G_END_DECLS
+#include <libglbarcode/lgl-barcode-postnet.h>
+#include <libglbarcode/lgl-barcode-onecode.h>
 
-#endif /* __BC_POSTNET_H__ */
+
+#endif /* __LIBGLBARCODE_H__ */
 
 
 
diff --git a/src/Makefile.am b/src/Makefile.am
index 77f4209..fb94449 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -1,10 +1,11 @@
 
-SUBDIRS= ../libglabels pixmaps
+SUBDIRS= ../libglabels ../libglbarcode pixmaps
 
 bin_PROGRAMS = glabels-3 glabels-3-batch
 
 INCLUDES = \
 	-I$(top_builddir)/libglabels				\
+	-I$(top_builddir)/libglbarcode				\
 	$(GLABELS_CFLAGS) 					\
 	$(LIBEBOOK_CFLAGS)					\
 	$(LIBBARCODE_CFLAGS)					\
@@ -22,6 +23,7 @@ glabels_3_LDFLAGS = -export-dynamic
 glabels_3_LDADD = 				\
 	$(GLABELS_LIBS)				\
 	../libglabels/$(LIBGLABELS_BRANCH).la	\
+	../libglbarcode/$(LIBGLBARCODE_BRANCH).la	\
 	$(LIBEBOOK_LIBS)		 	\
 	$(LIBBARCODE_LIBS)		 	\
 	$(LIBZINT_LIBS)				\
@@ -34,6 +36,7 @@ glabels_3_batch_LDFLAGS = -export-dynamic
 glabels_3_batch_LDADD = 			\
 	$(GLABELS_LIBS)				\
 	../libglabels/$(LIBGLABELS_BRANCH).la	\
+	../libglbarcode/$(LIBGLBARCODE_BRANCH).la	\
 	$(LIBEBOOK_LIBS)		 	\
 	$(LIBBARCODE_LIBS)		 	\
 	$(LIBZINT_LIBS)				\
@@ -115,18 +118,14 @@ glabels_3_SOURCES = 			\
 	print-op-dialog.h		\
 	template-designer.c		\
 	template-designer.h		\
-	bc.c				\
-	bc.h				\
 	bc-backends.c			\
 	bc-backends.h			\
+	bc-builtin.c			\
+	bc-builtin.h			\
 	bc-gnubarcode.c			\
 	bc-gnubarcode.h			\
 	bc-zint.c			\
 	bc-zint.h 			\
-	bc-onecode.c			\
-	bc-onecode.h			\
-	bc-postnet.c			\
-	bc-postnet.h			\
 	bc-iec16022.c			\
 	bc-iec16022.h			\
 	bc-iec18004.c			\
@@ -246,18 +245,14 @@ glabels_3_batch_SOURCES = 		\
 	print.h				\
 	print-op.c			\
 	print-op.h			\
-	bc.c				\
-	bc.h				\
 	bc-backends.c			\
 	bc-backends.h			\
+	bc-builtin.c			\
+	bc-builtin.h			\
 	bc-gnubarcode.c			\
 	bc-gnubarcode.h			\
 	bc-zint.c			\
 	bc-zint.h			\
-	bc-onecode.c			\
-	bc-onecode.h			\
-	bc-postnet.c			\
-	bc-postnet.h			\
 	bc-iec16022.c			\
 	bc-iec16022.h			\
 	bc-iec18004.c			\
@@ -338,8 +333,11 @@ EXTRA_DIST = \
 
 CLEANFILES = $(BUILT_SOURCES)
 
-$(bin_PROGRAMS): ../libglabels/$(LIBGLABELS_BRANCH).la
+$(bin_PROGRAMS): ../libglabels/$(LIBGLABELS_BRANCH).la ../libglbarcode/$(LIBGLBARCODE_BRANCH).la
 
 ../libglabels/$(LIBGLABELS_BRANCH).la:
 	cd ../libglabels; $(MAKE)
 
+../libglbarcode/$(LIBGLBARCODE_BRANCH).la:
+	cd ../libglbarcode; $(MAKE)
+
diff --git a/src/bc-backends.c b/src/bc-backends.c
index 3f69684..9f9904e 100644
--- a/src/bc-backends.c
+++ b/src/bc-backends.c
@@ -25,8 +25,7 @@
 #include <glib.h>
 #include <glib/gi18n.h>
 
-#include "bc-postnet.h"
-#include "bc-onecode.h"
+#include "bc-builtin.h"
 #include "bc-gnubarcode.h"
 #include "bc-zint.h"
 #include "bc-iec16022.h"
@@ -44,12 +43,12 @@
 /* Private types.                                         */
 /*========================================================*/
 
-typedef glBarcode *(*glBarcodeNewFunc) (const gchar    *id,
-                                        gboolean        text_flag,
-                                        gboolean        checksum_flag,
-                                        gdouble         w,
-                                        gdouble         h,
-                                        const gchar    *digits);
+typedef lglBarcode *(*glBarcodeNewFunc) (const gchar    *id,
+                                         gboolean        text_flag,
+                                         gboolean        checksum_flag,
+                                         gdouble         w,
+                                         gdouble         h,
+                                         const gchar    *digits);
 
 
 typedef struct {
@@ -99,24 +98,30 @@ static const Backend backends[] = {
 
 static const Style styles[] = {
 
-        { "built-in", "POSTNET", N_("POSTNET (any)"), gl_barcode_postnet_new,
+        { "built-in", "POSTNET", N_("POSTNET (any)"), gl_barcode_builtin_new,
           FALSE, FALSE, TRUE, FALSE, "12345-6789-12", FALSE, 11},
 
-        { "built-in", "POSTNET-5", N_("POSTNET-5 (ZIP only)"), gl_barcode_postnet_new,
+        { "built-in", "POSTNET-5", N_("POSTNET-5 (ZIP only)"), gl_barcode_builtin_new,
           FALSE, FALSE, TRUE, FALSE, "12345", FALSE, 5},
 
-        { "built-in", "POSTNET-9", N_("POSTNET-9 (ZIP+4)"), gl_barcode_postnet_new,
+        { "built-in", "POSTNET-9", N_("POSTNET-9 (ZIP+4)"), gl_barcode_builtin_new,
           FALSE, FALSE, TRUE, FALSE, "12345-6789", FALSE, 9},
 
-        { "built-in", "POSTNET-11", N_("POSTNET-11 (DPBC)"), gl_barcode_postnet_new,
+        { "built-in", "POSTNET-11", N_("POSTNET-11 (DPBC)"), gl_barcode_builtin_new,
           FALSE, FALSE, TRUE, FALSE, "12345-6789-12", FALSE, 11},
 
-        { "built-in", "CEPNET", N_("CEPNET"), gl_barcode_postnet_new,
+        { "built-in", "CEPNET", N_("CEPNET"), gl_barcode_builtin_new,
           FALSE, FALSE, TRUE, FALSE, "12345-678", FALSE, 8},
 
-        { "built-in", "ONECODE", N_("One Code"), gl_barcode_onecode_new,
+        { "built-in", "ONECODE", N_("One Code"), gl_barcode_builtin_new,
           FALSE, FALSE, TRUE, FALSE, "12345678901234567890", FALSE, 20},
 
+        { "built-in", "Code39", N_("Code 39"), gl_barcode_builtin_new,
+          TRUE, TRUE, TRUE, TRUE, "1234567890", TRUE, 10},
+
+        { "built-in", "Code39Ext", N_("Code 39 Extended"), gl_barcode_builtin_new,
+          TRUE, TRUE, TRUE, TRUE, "1234567890", TRUE, 10},
+
 #ifdef HAVE_LIBBARCODE
 
         { "gnu-barcode", "EAN", N_("EAN (any)"), gl_barcode_gnubarcode_new,
@@ -241,7 +246,7 @@ static const Style styles[] = {
           TRUE, TRUE, TRUE, FALSE, "12345678", TRUE, 8},
 
         { "zint", "Code39", N_("Code 39"), gl_barcode_zint_new,
-          TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
+          TRUE, TRUE, FALSE, FALSE, "0000000000", TRUE, 10},
           
         { "zint", "Code39E", N_("Code 39 Extended"),  gl_barcode_zint_new,
           TRUE, TRUE, TRUE, FALSE, "0000000000", TRUE, 10},
@@ -796,7 +801,7 @@ gl_barcode_backends_style_get_prefered_n (const gchar *backend_id,
 /*****************************************************************************/
 /* Call appropriate barcode backend to create barcode in intermediate format.*/
 /*****************************************************************************/
-glBarcode *
+lglBarcode *
 gl_barcode_backends_new_barcode (const gchar    *backend_id,
                                  const gchar    *id,
                                  gboolean        text_flag,
@@ -805,8 +810,8 @@ gl_barcode_backends_new_barcode (const gchar    *backend_id,
                                  gdouble         h,
                                  const gchar    *digits)
 {
-        glBarcode *gbc;
-        gint       i;
+        lglBarcode *gbc;
+        gint        i;
 
         g_return_val_if_fail (digits!=NULL, NULL);
 
diff --git a/src/bc-backends.h b/src/bc-backends.h
index 1cd2b12..8ed764d 100644
--- a/src/bc-backends.h
+++ b/src/bc-backends.h
@@ -22,7 +22,7 @@
 #define __BC_BACKENDS_H__
 
 #include <glib.h>
-#include "bc.h"
+#include <libglbarcode.h>
 
 G_BEGIN_DECLS
 
@@ -62,7 +62,7 @@ gboolean         gl_barcode_backends_style_can_freeform   (const gchar    *backe
 guint            gl_barcode_backends_style_get_prefered_n (const gchar    *backend_id,
                                                            const gchar    *id);
 
-glBarcode       *gl_barcode_backends_new_barcode          (const gchar    *backend_id,
+lglBarcode      *gl_barcode_backends_new_barcode          (const gchar    *backend_id,
                                                            const gchar    *id,
                                                            gboolean        text_flag,
                                                            gboolean        checksum_flag,
diff --git a/src/bc-builtin.c b/src/bc-builtin.c
new file mode 100644
index 0000000..e50ebc8
--- /dev/null
+++ b/src/bc-builtin.c
@@ -0,0 +1,97 @@
+/*
+ *  bc-builtin.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/>.
+ */
+
+/*
+ * This module implements the BUILTIN barcode specified in the USPS
+ * publication 25, Mar 2001.
+ */
+
+#include <config.h>
+
+#include "bc-builtin.h"
+
+#include "debug.h"
+
+
+/*========================================================*/
+/* Private macros and constants.                          */
+/*========================================================*/
+
+
+/*===========================================*/
+/* Private globals                           */
+/*===========================================*/
+
+
+/*===========================================*/
+/* Local function prototypes                 */
+/*===========================================*/
+
+
+/****************************************************************************/
+/* Generate list of lines that form the barcode for the given digits.       */
+/****************************************************************************/
+lglBarcode *
+gl_barcode_builtin_new (const gchar    *id,
+			gboolean        text_flag,
+			gboolean        checksum_flag,
+			gdouble         w,
+			gdouble         h,
+			const gchar    *digits)
+{
+	if ( (g_ascii_strcasecmp (id, "POSTNET") == 0) ) {
+                return lgl_barcode_create (LGL_BARCODE_TYPE_POSTNET, text_flag, checksum_flag, w, h, digits);
+	}
+	if ( (g_ascii_strcasecmp (id, "POSTNET-5") == 0) ) {
+                return lgl_barcode_create (LGL_BARCODE_TYPE_POSTNET_5, text_flag, checksum_flag, w, h, digits);
+	}
+	if ( (g_ascii_strcasecmp (id, "POSTNET-9") == 0) ) {
+                return lgl_barcode_create (LGL_BARCODE_TYPE_POSTNET_9, text_flag, checksum_flag, w, h, digits);
+	}
+	if ( (g_ascii_strcasecmp (id, "POSTNET-11") == 0) ) {
+                return lgl_barcode_create (LGL_BARCODE_TYPE_POSTNET_11, text_flag, checksum_flag, w, h, digits);
+	}
+	if ( (g_ascii_strcasecmp (id, "CEPNET") == 0) ) {
+                return lgl_barcode_create (LGL_BARCODE_TYPE_CEPNET, text_flag, checksum_flag, w, h, digits);
+	}
+	if ( (g_ascii_strcasecmp (id, "ONECODE") == 0) ) {
+                return lgl_barcode_create (LGL_BARCODE_TYPE_ONECODE, text_flag, checksum_flag, w, h, digits);
+	}
+	if ( (g_ascii_strcasecmp (id, "Code39") == 0) ) {
+                return lgl_barcode_create (LGL_BARCODE_TYPE_CODE39, text_flag, checksum_flag, w, h, digits);
+	}
+	if ( (g_ascii_strcasecmp (id, "Code39Ext") == 0) ) {
+                return lgl_barcode_create (LGL_BARCODE_TYPE_CODE39_EXT, text_flag, checksum_flag, w, h, digits);
+	}
+
+        g_message ("Invalid builtin barcode ID: \"%s\"\n", id);
+        return NULL;
+}
+
+
+
+/*
+ * 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-postnet.h b/src/bc-builtin.h
similarity index 67%
rename from src/bc-postnet.h
rename to src/bc-builtin.h
index 0945670..459b413 100644
--- a/src/bc-postnet.h
+++ b/src/bc-builtin.h
@@ -1,5 +1,5 @@
 /*
- *  bc-postnet.h
+ *  bc-builtin.h
  *  Copyright (C) 2001-2009  Jim Evins <evins snaught com>.
  *
  *  This file is part of gLabels.
@@ -18,23 +18,24 @@
  *  along with gLabels.  If not, see <http://www.gnu.org/licenses/>.
  */
 
-#ifndef __BC_POSTNET_H__
-#define __BC_POSTNET_H__
+#ifndef __BC_BUILTIN_H__
+#define __BC_BUILTIN_H__
+
+#include <libglbarcode.h>
 
-#include "bc.h"
 
 G_BEGIN_DECLS
 
-glBarcode *gl_barcode_postnet_new (const gchar    *id,
-				   gboolean        text_flag,
-				   gboolean        checksum_flag,
-				   gdouble         w,
-				   gdouble         h,
-				   const gchar    *digits);
+lglBarcode *gl_barcode_builtin_new (const gchar    *id,
+                                    gboolean        text_flag,
+                                    gboolean        checksum_flag,
+                                    gdouble         w,
+                                    gdouble         h,
+                                    const gchar    *digits);
 
 G_END_DECLS
 
-#endif /* __BC_POSTNET_H__ */
+#endif /* __BC_BUILTIN_H__ */
 
 
 
diff --git a/src/bc-gnubarcode.c b/src/bc-gnubarcode.c
index 327b02f..88b9e28 100644
--- a/src/bc-gnubarcode.c
+++ b/src/bc-gnubarcode.c
@@ -42,8 +42,8 @@
 /*===========================================*/
 /* Local function prototypes                 */
 /*===========================================*/
-static glBarcode *render_pass1     (struct Barcode_Item *bci,
-				    gint                 flags);
+static lglBarcode *render_pass1     (struct Barcode_Item *bci,
+                                     gint                 flags);
 
 static gboolean   is_length_valid  (const gchar         *digits,
 				    gint                 n1,
@@ -61,7 +61,7 @@ static gboolean   is_length2_valid (const gchar         *digits,
 /*****************************************************************************/
 /* Generate intermediate representation of barcode.                          */
 /*****************************************************************************/
-glBarcode *
+lglBarcode *
 gl_barcode_gnubarcode_new (const gchar    *id,
 			   gboolean        text_flag,
 			   gboolean        checksum_flag,
@@ -69,7 +69,7 @@ gl_barcode_gnubarcode_new (const gchar    *id,
 			   gdouble         h,
 			   const gchar    *digits)
 {
-	glBarcode           *gbc;
+	lglBarcode          *gbc;
 	struct Barcode_Item *bci;
 	gint                 flags;
 
@@ -202,7 +202,7 @@ gl_barcode_gnubarcode_new (const gchar    *id,
 
 
 /*--------------------------------------------------------------------------
- * PRIVATE.  Render to glBarcode intermediate representation of barcode.
+ * PRIVATE.  Render to lglBarcode intermediate representation of barcode.
  *
  *  Some of this code is borrowed from the postscript renderer (ps.c)
  *  from the GNU barcode library:
@@ -211,12 +211,12 @@ gl_barcode_gnubarcode_new (const gchar    *id,
  *     Copyright (C) 1999 Prosa Srl. (prosa prosa it)
  *
  *--------------------------------------------------------------------------*/
-static glBarcode *
+static lglBarcode *
 render_pass1 (struct Barcode_Item *bci,
 	      gint                 flags)
 {
 	gint                 validbits = BARCODE_NO_ASCII;
-	glBarcode           *gbc;
+	lglBarcode          *gbc;
 	gdouble              scalef = 1.0;
 	gdouble              x;
 	gint                 i, j, barlen;
@@ -282,7 +282,7 @@ render_pass1 (struct Barcode_Item *bci,
 		bci->height = i * scalef;
 	}
 
-	gbc = gl_barcode_new ();
+	gbc = lgl_barcode_new ();
 
 	/* Now traverse the code string and create a list of lines */
 	x = bci->margin + (bci->partial[0] - '0') * scalef;
@@ -313,7 +313,7 @@ render_pass1 (struct Barcode_Item *bci,
 					yr -= (isdigit (*p) ? 20 : 10) * scalef;
 				}
 			}
-                        gl_barcode_add_line (gbc, x0, y0, yr, (j * scalef) - SHRINK_AMOUNT);
+                        lgl_barcode_add_line (gbc, x0, y0, yr, (j * scalef) - SHRINK_AMOUNT);
 		}
 		x += j * scalef;
 
@@ -341,7 +341,7 @@ render_pass1 (struct Barcode_Item *bci,
 			} else {
 				y0 = bci->margin;
 			}
-                        gl_barcode_add_char (gbc, x0, y0, (f2 * FONT_SCALE * scalef), c);
+                        lgl_barcode_add_char (gbc, x0, y0, (f2 * FONT_SCALE * scalef), c);
 		}
 	}
 
diff --git a/src/bc-gnubarcode.h b/src/bc-gnubarcode.h
index ac96b34..6441a48 100644
--- a/src/bc-gnubarcode.h
+++ b/src/bc-gnubarcode.h
@@ -21,16 +21,16 @@
 #ifndef __BC_GNUBARCODE_H__
 #define __BC_GNUBARCODE_H__
 
-#include "bc.h"
+#include <libglbarcode.h>
 
 G_BEGIN_DECLS
 
-glBarcode *gl_barcode_gnubarcode_new (const gchar    *id,
-				      gboolean        text_flag,
-				      gboolean        checksum_flag,
-				      gdouble         w,
-				      gdouble         h,
-				      const gchar    *digits);
+lglBarcode *gl_barcode_gnubarcode_new (const gchar    *id,
+                                       gboolean        text_flag,
+                                       gboolean        checksum_flag,
+                                       gdouble         w,
+                                       gdouble         h,
+                                       const gchar    *digits);
 
 G_END_DECLS
 
diff --git a/src/bc-iec16022.c b/src/bc-iec16022.c
index dbd06ec..0719ed5 100644
--- a/src/bc-iec16022.c
+++ b/src/bc-iec16022.c
@@ -42,17 +42,17 @@
 /*===========================================*/
 /* Local function prototypes                 */
 /*===========================================*/
-static glBarcode *render_iec16022 (const gchar *grid,
-                                   gint         i_width,
-                                   gint         i_height,
-                                   gdouble      w,
-                                   gdouble      h);
+static lglBarcode *render_iec16022 (const gchar *grid,
+                                    gint         i_width,
+                                    gint         i_height,
+                                    gdouble      w,
+                                    gdouble      h);
 
 
 /*****************************************************************************/
 /* Generate intermediate representation of barcode.                          */
 /*****************************************************************************/
-glBarcode *
+lglBarcode *
 gl_barcode_iec16022_new (const gchar    *id,
                          gboolean        text_flag,
                          gboolean        checksum_flag,
@@ -62,7 +62,7 @@ gl_barcode_iec16022_new (const gchar    *id,
 {
         gchar               *grid;
         gint                 i_width, i_height;
-        glBarcode           *gbc;
+        lglBarcode          *gbc;
 
         if ( strlen (digits) == 0 )
         {
@@ -86,16 +86,16 @@ gl_barcode_iec16022_new (const gchar    *id,
 
 
 /*--------------------------------------------------------------------------
- * PRIVATE.  Render to glBarcode intermediate representation of barcode.
+ * PRIVATE.  Render to lglBarcode intermediate representation of barcode.
  *--------------------------------------------------------------------------*/
-static glBarcode *
+static lglBarcode *
 render_iec16022 (const gchar *grid,
                  gint         i_width,
                  gint         i_height,
                  gdouble      w,
                  gdouble      h)
 {
-        glBarcode          *gbc;
+        lglBarcode         *gbc;
         gint                x, y;
         gdouble             aspect_ratio, pixel_size;
 
@@ -115,7 +115,7 @@ render_iec16022 (const gchar *grid,
                 pixel_size = MIN_PIXEL_SIZE;
         }
 
-        gbc = gl_barcode_new ();
+        gbc = lgl_barcode_new ();
 
         /* Now traverse the code string and create a list of boxes */
         for ( y = i_height-1; y >= 0; y-- )
@@ -126,7 +126,7 @@ render_iec16022 (const gchar *grid,
 
                         if (*grid++)
                         {
-                                gl_barcode_add_box (gbc, x*pixel_size, y*pixel_size, pixel_size, pixel_size);
+                                lgl_barcode_add_box (gbc, x*pixel_size, y*pixel_size, pixel_size, pixel_size);
                         }
 
                 }
diff --git a/src/bc-iec16022.h b/src/bc-iec16022.h
index 64655b0..8695408 100644
--- a/src/bc-iec16022.h
+++ b/src/bc-iec16022.h
@@ -21,16 +21,16 @@
 #ifndef __BC_IEC16022_H__
 #define __BC_IEC16022_H__
 
-#include "bc.h"
+#include <libglbarcode.h>
 
 G_BEGIN_DECLS
 
-glBarcode *gl_barcode_iec16022_new (const gchar    *id,
-                                    gboolean        text_flag,
-                                    gboolean        checksum_flag,
-                                    gdouble         w,
-                                    gdouble         h,
-                                    const gchar    *digits);
+lglBarcode *gl_barcode_iec16022_new (const gchar    *id,
+                                     gboolean        text_flag,
+                                     gboolean        checksum_flag,
+                                     gdouble         w,
+                                     gdouble         h,
+                                     const gchar    *digits);
 
 G_END_DECLS
 
diff --git a/src/bc-iec18004.c b/src/bc-iec18004.c
index 0237352..396b55b 100644
--- a/src/bc-iec18004.c
+++ b/src/bc-iec18004.c
@@ -43,17 +43,17 @@
 /*===========================================*/
 /* Local function prototypes                 */
 /*===========================================*/
-static glBarcode *render_iec18004 (const gchar *grid,
-                                   gint         i_width,
-                                   gint         i_height,
-                                   gdouble      w,
-                                   gdouble      h);
+static lglBarcode *render_iec18004 (const gchar *grid,
+                                    gint         i_width,
+                                    gint         i_height,
+                                    gdouble      w,
+                                    gdouble      h);
 
 
 /*****************************************************************************/
 /* Generate intermediate representation of barcode.                          */
 /*****************************************************************************/
-glBarcode *
+lglBarcode *
 gl_barcode_iec18004_new (const gchar    *id,
                          gboolean        text_flag,
                          gboolean        checksum_flag,
@@ -62,7 +62,7 @@ gl_barcode_iec18004_new (const gchar    *id,
                          const gchar    *digits)
 {
         gint             i_width, i_height;
-        glBarcode       *gbc;
+        lglBarcode      *gbc;
 	QRcode          *qrcode;
 
         if ( strlen (digits) == 0 )
@@ -91,16 +91,16 @@ gl_barcode_iec18004_new (const gchar    *id,
 
 
 /*--------------------------------------------------------------------------
- * PRIVATE.  Render to glBarcode intermediate representation of barcode.
+ * PRIVATE.  Render to lglBarcode intermediate representation of barcode.
  *--------------------------------------------------------------------------*/
-static glBarcode *
+static lglBarcode *
 render_iec18004 (const gchar *grid,
                  gint         i_width,
                  gint         i_height,
                  gdouble      w,
                  gdouble      h)
 {
-        glBarcode          *gbc;
+        lglBarcode         *gbc;
         gint                x, y;
         gdouble             aspect_ratio, pixel_size;
 
@@ -120,7 +120,7 @@ render_iec18004 (const gchar *grid,
                 pixel_size = MIN_PIXEL_SIZE;
         }
 
-        gbc = gl_barcode_new ();
+        gbc = lgl_barcode_new ();
 
         /* Now traverse the code string and create a list of boxes */
         for ( y = 0; y < i_height; y++ )
@@ -135,7 +135,7 @@ render_iec18004 (const gchar *grid,
                          * bits are meaningless for us. */
                         if ((*grid++) & 1)
                         {
-                                gl_barcode_add_box (gbc, x*pixel_size, y*pixel_size, pixel_size, pixel_size);
+                                lgl_barcode_add_box (gbc, x*pixel_size, y*pixel_size, pixel_size, pixel_size);
                         }
 
                 }
diff --git a/src/bc-iec18004.h b/src/bc-iec18004.h
index 2c3e7ee..99d3c3d 100644
--- a/src/bc-iec18004.h
+++ b/src/bc-iec18004.h
@@ -21,16 +21,16 @@
 #ifndef __BC_IEC18004_H__
 #define __BC_IEC18004_H__
 
-#include "bc.h"
+#include <libglbarcode.h>
 
 G_BEGIN_DECLS
 
-glBarcode *gl_barcode_iec18004_new (const gchar    *id,
-                                    gboolean        text_flag,
-                                    gboolean        checksum_flag,
-                                    gdouble         w,
-                                    gdouble         h,
-                                    const gchar    *digits);
+lglBarcode *gl_barcode_iec18004_new (const gchar    *id,
+                                     gboolean        text_flag,
+                                     gboolean        checksum_flag,
+                                     gdouble         w,
+                                     gdouble         h,
+                                     const gchar    *digits);
 
 G_END_DECLS
 
diff --git a/src/bc-zint.c b/src/bc-zint.c
index d96e5d7..e68efc8 100644
--- a/src/bc-zint.c
+++ b/src/bc-zint.c
@@ -42,14 +42,14 @@
 /*===========================================*/
 /* Local function prototypes                 */
 /*===========================================*/
-static glBarcode *render_zint     (struct zint_symbol *symbol, gboolean text_flag);
+static lglBarcode *render_zint     (struct zint_symbol *symbol, gboolean text_flag);
 
 
 
 /*****************************************************************************/
 /* Generate intermediate representation of barcode.                          */
 /*****************************************************************************/
-glBarcode *
+lglBarcode *
 gl_barcode_zint_new (const gchar          *id,
 			   gboolean        text_flag,
 			   gboolean        checksum_flag,
@@ -57,7 +57,7 @@ gl_barcode_zint_new (const gchar          *id,
 			   gdouble         h,
 			   const gchar    *digits)
 {
-	glBarcode           *gbc;
+	lglBarcode          *gbc;
 	struct zint_symbol  *symbol;
 	gint		     result;
 
@@ -173,11 +173,11 @@ gl_barcode_zint_new (const gchar          *id,
 
 
 /*--------------------------------------------------------------------------
- * PRIVATE. Render to glBarcode the provided Zint symbol.
+ * PRIVATE. Render to lglBarcode the provided Zint symbol.
  *--------------------------------------------------------------------------*/
-static glBarcode *render_zint(struct zint_symbol *symbol, gboolean text_flag)
+static lglBarcode *render_zint(struct zint_symbol *symbol, gboolean text_flag)
 {
-        glBarcode            *gbc;
+        lglBarcode            *gbc;
 
         struct zint_render         *render;
         struct zint_render_line    *zline;
@@ -186,30 +186,30 @@ static glBarcode *render_zint(struct zint_symbol *symbol, gboolean text_flag)
         struct zint_render_hexagon *zhexagon;
 
         render = symbol->rendered;
-        gbc = gl_barcode_new ();
+        gbc = lgl_barcode_new ();
 	
         for ( zline = render->lines; zline != NULL; zline = zline->next )
         {
-                gl_barcode_add_box (gbc, zline->x, zline->y, zline->width, zline->length);
+                lgl_barcode_add_box (gbc, zline->x, zline->y, zline->width, zline->length);
         }
 
         for ( zring = render->rings; zring != NULL; zring = zring->next )
         {
-                gl_barcode_add_ring (gbc, zring->x, zring->y, zring->radius, zring->line_width);
+                lgl_barcode_add_ring (gbc, zring->x, zring->y, zring->radius, zring->line_width);
         }
 
         for ( zhexagon = render->hexagons; zhexagon != NULL; zhexagon = zhexagon->next )
         {
-                gl_barcode_add_hexagon (gbc, zhexagon->x, zhexagon->y);
+                lgl_barcode_add_hexagon (gbc, zhexagon->x, zhexagon->y, 2.89);
         }
 
         if(text_flag)
         {
                 for ( zstring = render->strings; zstring != NULL; zstring = zstring->next )
                 {
-                        gl_barcode_add_string (gbc,
-                                               zstring->x, zstring->y,
-                                               zstring->fsize, (gchar *)zstring->text, zstring->length);
+                        lgl_barcode_add_string (gbc,
+                                                zstring->x, zstring->y,
+                                                zstring->fsize, (gchar *)zstring->text, zstring->length);
                 }
         }
 
diff --git a/src/bc-zint.h b/src/bc-zint.h
index c0a797d..2355363 100644
--- a/src/bc-zint.h
+++ b/src/bc-zint.h
@@ -22,16 +22,16 @@
 #ifndef __BC_ZINT_H__
 #define __BC_ZINT_H__
 
-#include "bc.h"
+#include <libglbarcode.h>
 
 G_BEGIN_DECLS
 
-glBarcode *gl_barcode_zint_new (const gchar    *id,
-				      gboolean        text_flag,
-				      gboolean        checksum_flag,
-				      gdouble         w,
-				      gdouble         h,
-				      const gchar    *digits);
+lglBarcode *gl_barcode_zint_new (const gchar    *id,
+                                 gboolean        text_flag,
+                                 gboolean        checksum_flag,
+                                 gdouble         w,
+                                 gdouble         h,
+                                 const gchar    *digits);
 
 G_END_DECLS
 
diff --git a/src/label-barcode.c b/src/label-barcode.c
index 8b1810d..6cc93b5 100644
--- a/src/label-barcode.c
+++ b/src/label-barcode.c
@@ -36,6 +36,8 @@
 #define FONT_SCALE (72.0/96.0)
 #define PI 3.141592654
 
+#define GL_BARCODE_FONT_FAMILY      "Sans"
+
 
 /*========================================================*/
 /* Private types.                                         */
@@ -302,7 +304,7 @@ get_size (glLabelObject *object,
         glLabelBarcode      *lbc = (glLabelBarcode *)object;
         gchar               *data;
         gdouble              w_parent, h_parent;
-        glBarcode           *gbc;
+        lglBarcode          *gbc;
 
         gl_debug (DEBUG_LABEL, "START");
 
@@ -354,7 +356,7 @@ get_size (glLabelObject *object,
                 *h = 72;
         }
 
-        gl_barcode_free (&gbc);
+        lgl_barcode_free (gbc);
 
         gl_debug (DEBUG_LABEL, "END");
 }
@@ -413,26 +415,15 @@ draw_object (glLabelObject *object,
 {
         gdouble               x0, y0;
         cairo_matrix_t        matrix;
-        glBarcode            *gbc;
-        glBarcodeShape       *shape;
-        glBarcodeShapeLine   *line;
-        glBarcodeShapeBox    *box;
-        glBarcodeShapeRing   *ring;
-        glBarcodeShapeHexagon *hexagon;
-        glBarcodeShapeChar   *bchar;
-        glBarcodeShapeString *bstring;
-        GList                *p;
-        gdouble               x_offset, y_offset;
+        lglBarcode           *gbc;
         PangoLayout          *layout;
         PangoFontDescription *desc;
-        gchar                *text, *cstring;
+        gchar                *text;
         glTextNode           *text_node;
         glLabelBarcodeStyle  *style;
         guint                 color;
         glColorNode          *color_node;
         gdouble               w, h;
-        gint                  iw, ih;
-        gdouble               layout_width;
 
         gl_debug (DEBUG_LABEL, "START");
 
@@ -487,111 +478,9 @@ draw_object (glLabelObject *object,
 
         } else {
 
-                for (p = gbc->shapes; p != NULL; p = p->next) {
-                        shape = (glBarcodeShape *)p->data;
-                        switch (shape->type)
-                        {
-
-                        case GL_BARCODE_SHAPE_LINE:
-                                line = (glBarcodeShapeLine *) shape;
-
-                                cairo_move_to (cr, line->x, line->y);
-                                cairo_line_to (cr, line->x, line->y + line->length);
-                                cairo_set_line_width (cr, line->width);
-                                cairo_stroke (cr);
-
-                                break;
-
-                        case GL_BARCODE_SHAPE_BOX:
-                                box = (glBarcodeShapeBox *) shape;
-
-                                cairo_rectangle (cr, box->x, box->y, box->width, box->height);
-                                cairo_fill (cr);
-
-                                break;
-
-                        case GL_BARCODE_SHAPE_CHAR:
-                                bchar = (glBarcodeShapeChar *) shape;
-
-                                layout = pango_cairo_create_layout (cr);
-
-                                desc = pango_font_description_new ();
-                                pango_font_description_set_family (desc, GL_BARCODE_FONT_FAMILY);
-                                pango_font_description_set_size   (desc, bchar->fsize * PANGO_SCALE * FONT_SCALE);
-                                pango_layout_set_font_description (layout, desc);
-                                pango_font_description_free       (desc);
-
-                                cstring = g_strdup_printf ("%c", bchar->c);
-                                pango_layout_set_text (layout, cstring, -1);
-                                g_free (cstring);
-
-                                y_offset = 0.2 * bchar->fsize;
-
-                                cairo_move_to (cr, bchar->x, bchar->y-y_offset);
-                                pango_cairo_show_layout (cr, layout);
-
-                                g_object_unref (layout);
-
-                                break;
-
-                        case GL_BARCODE_SHAPE_STRING:
-                                bstring = (glBarcodeShapeString *) shape;
-
-                                layout = pango_cairo_create_layout (cr);
-
-                                desc = pango_font_description_new ();
-                                pango_font_description_set_family (desc, GL_BARCODE_FONT_FAMILY);
-                                pango_font_description_set_size   (desc, bstring->fsize * PANGO_SCALE * FONT_SCALE);
-                                pango_layout_set_font_description (layout, desc);
-                                pango_font_description_free       (desc);
-
-                                pango_layout_set_text (layout, bstring->string, -1);
-
-                                pango_layout_get_size (layout, &iw, &ih);
-                                layout_width = (gdouble)iw / (gdouble)PANGO_SCALE;
-
-                                x_offset = layout_width / 2.0;
-                                y_offset = 0.2 * bstring->fsize;
-
-                                cairo_move_to (cr, (bstring->x - x_offset), (bstring->y - y_offset));
-                                pango_cairo_show_layout (cr, layout);
-
-                                g_object_unref (layout);
-
-                                break;
-
-                        case GL_BARCODE_SHAPE_RING:
-                                ring = (glBarcodeShapeRing *) shape;
-
-                                cairo_arc (cr, ring->x, ring->y, ring->radius, 0.0, 2 * PI);
-                                cairo_set_line_width (cr, ring->line_width);
-                                cairo_stroke (cr);
-
-                                break;
-
-                        case GL_BARCODE_SHAPE_HEXAGON:
-                                hexagon = (glBarcodeShapeHexagon *) shape;
-
-                                cairo_move_to (cr, hexagon->x, hexagon->y);
-                                cairo_line_to (cr, hexagon->x + 1.25, hexagon->y + 0.70);
-                                cairo_line_to (cr, hexagon->x + 1.25, hexagon->y + 2.18);
-                                cairo_line_to (cr, hexagon->x, hexagon->y + 2.89);
-                                cairo_line_to (cr, hexagon->x - 1.25, hexagon->y + 2.18);
-                                cairo_line_to (cr, hexagon->x - 1.25, hexagon->y + 0.70);
-                                cairo_close_path (cr);
-                                cairo_fill (cr);
-
-                                break;
-
-                        default:
-                                g_assert_not_reached ();
-                                break;
-
-                        }
-
-                }
+                lgl_barcode_render_to_cairo (gbc, cr);
 
-                gl_barcode_free (&gbc);
+                lgl_barcode_free (gbc);
 
         }
 



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