From: Jim Evins Date: Sat, 30 Oct 2010 21:37:37 +0000 (-0400) Subject: Refactored core barcode subsystem. X-Git-Tag: glabels-2_3_1~159 X-Git-Url: https://git.sur5r.net/?a=commitdiff_plain;h=edaa3e0b6dec8f8ba81c05b5a196a90b1ebb1ca2;p=glabels 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 --- diff --git a/.gitignore b/.gitignore index ca042820..84676e3d 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 efc7f290..b2dee282 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 836e342f..37b047da 100644 --- a/configure.ac +++ b/configure.ac @@ -44,6 +44,12 @@ dnl --------------------------------------------------------------------------- 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 --------------------------------------------------------------------------- @@ -66,6 +72,28 @@ LIBGLABELS_A=0 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 --------------------------------------------------------------------------- @@ -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) @@ -123,6 +156,19 @@ AC_SUBST(LIBGLABELS_CFLAGS) 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 --------------------------------------------------------------------------- @@ -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 00000000..7a884dfc --- /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 00000000..4393fc2a --- /dev/null +++ b/libglbarcode/lgl-barcode-code39.c @@ -0,0 +1,403 @@ +/* + * lgl-barcode-code39.c + * Copyright (C) 2001-2010 Jim Evins . + * + * 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 . + */ + +#include + +#include "lgl-barcode-code39.h" + +#include +#include +#include + + +/*========================================================*/ +/* 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/libglbarcode/lgl-barcode-code39.h b/libglbarcode/lgl-barcode-code39.h new file mode 100644 index 00000000..dccaaae9 --- /dev/null +++ b/libglbarcode/lgl-barcode-code39.h @@ -0,0 +1,49 @@ +/* + * lgl-barcode-code39.h + * Copyright (C) 2001-2010 Jim Evins . + * + * 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 . + */ + +#ifndef __LGL_BARCODE_CODE39_H__ +#define __LGL_BARCODE_CODE39_H__ + +#include "lgl-barcode.h" +#include "lgl-barcode-type.h" + +G_BEGIN_DECLS + +lglBarcode *lgl_barcode_code39_new (lglBarcodeType type, + gboolean text_flag, + gboolean checksum_flag, + gdouble w, + gdouble h, + const gchar *data); + +G_END_DECLS + +#endif /* __LGL_BARCODE_CODE39_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/lgl-barcode-create.c b/libglbarcode/lgl-barcode-create.c new file mode 100644 index 00000000..fe2dadcd --- /dev/null +++ b/libglbarcode/lgl-barcode-create.c @@ -0,0 +1,99 @@ +/* + * lgl-barcode-create.c + * Copyright (C) 2010 Jim Evins . + * + * 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 . + */ + +#include + +#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/libglbarcode/lgl-barcode-create.h b/libglbarcode/lgl-barcode-create.h new file mode 100644 index 00000000..61cb5917 --- /dev/null +++ b/libglbarcode/lgl-barcode-create.h @@ -0,0 +1,52 @@ +/* + * lgl-barcode-create.h + * Copyright (C) 2001-2010 Jim Evins . + * + * 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 . + */ + +#ifndef __LGL_BARCODE_CREATE_H__ +#define __LGL_BARCODE_CREATE_H__ + +#include + +#include "lgl-barcode.h" +#include "lgl-barcode-type.h" + +G_BEGIN_DECLS + + +lglBarcode *lgl_barcode_create (lglBarcodeType type, + gboolean text_flag, + gboolean checksum_flag, + gdouble w, + gdouble h, + const gchar *data); + +G_END_DECLS + +#endif /* __LGL_BARCODE_CREATE_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/lgl-barcode-onecode.c b/libglbarcode/lgl-barcode-onecode.c new file mode 100644 index 00000000..ba06ec31 --- /dev/null +++ b/libglbarcode/lgl-barcode-onecode.c @@ -0,0 +1,747 @@ +/* + * lgl-barcode-onecode.c + * Copyright (C) 2010 Jim Evins . + * + * 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 . + */ + +/* + * This module implements the Intelligent Mail (OneCode) barcode + * specified in the USPS specification USPS-B-3200E, 07/08/05. + */ + +#include + +#include "lgl-barcode-onecode.h" + +#include +#include +#include + +/*========================================================*/ +/* Private macros and constants. */ +/*========================================================*/ + +#define CHAR_A 0 +#define CHAR_B 1 +#define CHAR_C 2 +#define CHAR_D 3 +#define CHAR_E 4 +#define CHAR_F 5 +#define CHAR_G 6 +#define CHAR_H 7 +#define CHAR_I 8 +#define CHAR_J 9 + +#define PTS_PER_INCH 72.0 + +#define ONECODE_BAR_WIDTH ( 0.02 * PTS_PER_INCH ) +#define ONECODE_FULL_HEIGHT ( 0.145 * PTS_PER_INCH ) +#define ONECODE_ASCENDER_HEIGHT ( 0.0965 * PTS_PER_INCH ) +#define ONECODE_DESCENDER_HEIGHT ( 0.0965 * PTS_PER_INCH ) +#define ONECODE_TRACKER_HEIGHT ( 0.048 * PTS_PER_INCH ) +#define ONECODE_FULL_OFFSET 0 +#define ONECODE_ASCENDER_OFFSET 0 +#define ONECODE_DESCENDER_OFFSET ( 0.0485 * PTS_PER_INCH ) +#define ONECODE_TRACKER_OFFSET ( 0.0485 * PTS_PER_INCH ) +#define ONECODE_BAR_PITCH ( 0.0458 * PTS_PER_INCH ) +#define ONECODE_HORIZ_MARGIN ( 0.125 * PTS_PER_INCH ) +#define ONECODE_VERT_MARGIN ( 0.028 * PTS_PER_INCH ) + + +/*========================================================*/ +/* Private types. */ +/*========================================================*/ + +typedef struct { + guchar byte[13]; +} Int104; + +typedef struct { + struct { gint i; gint mask; } descender; + struct { gint i; gint mask; } ascender; +} BarMapEntry; + + +/*===========================================*/ +/* Private globals */ +/*===========================================*/ + +static BarMapEntry bar_map[] = { + /* 1 */ { { CHAR_H, 1<<2 }, { CHAR_E, 1<<3 } }, + /* 2 */ { { CHAR_B, 1<<10 }, { CHAR_A, 1<<0 } }, + /* 3 */ { { CHAR_J, 1<<12 }, { CHAR_C, 1<<8 } }, + /* 4 */ { { CHAR_F, 1<<5 }, { CHAR_G, 1<<11 } }, + /* 5 */ { { CHAR_I, 1<<9 }, { CHAR_D, 1<<1 } }, + /* 6 */ { { CHAR_A, 1<<1 }, { CHAR_F, 1<<12 } }, + /* 7 */ { { CHAR_C, 1<<5 }, { CHAR_B, 1<<8 } }, + /* 8 */ { { CHAR_E, 1<<4 }, { CHAR_J, 1<<11 } }, + /* 9 */ { { CHAR_G, 1<<3 }, { CHAR_I, 1<<10 } }, + /* 10 */ { { CHAR_D, 1<<9 }, { CHAR_H, 1<<6 } }, + /* 11 */ { { CHAR_F, 1<<11 }, { CHAR_B, 1<<4 } }, + /* 12 */ { { CHAR_I, 1<<5 }, { CHAR_C, 1<<12 } }, + /* 13 */ { { CHAR_J, 1<<10 }, { CHAR_A, 1<<2 } }, + /* 14 */ { { CHAR_H, 1<<1 }, { CHAR_G, 1<<7 } }, + /* 15 */ { { CHAR_D, 1<<6 }, { CHAR_E, 1<<9 } }, + /* 16 */ { { CHAR_A, 1<<3 }, { CHAR_I, 1<<6 } }, + /* 17 */ { { CHAR_G, 1<<4 }, { CHAR_C, 1<<7 } }, + /* 18 */ { { CHAR_B, 1<<1 }, { CHAR_J, 1<<9 } }, + /* 19 */ { { CHAR_H, 1<<10 }, { CHAR_F, 1<<2 } }, + /* 20 */ { { CHAR_E, 1<<0 }, { CHAR_D, 1<<8 } }, + /* 21 */ { { CHAR_G, 1<<2 }, { CHAR_A, 1<<4 } }, + /* 22 */ { { CHAR_I, 1<<11 }, { CHAR_B, 1<<0 } }, + /* 23 */ { { CHAR_J, 1<<8 }, { CHAR_D, 1<<12 } }, + /* 24 */ { { CHAR_C, 1<<6 }, { CHAR_H, 1<<7 } }, + /* 25 */ { { CHAR_F, 1<<1 }, { CHAR_E, 1<<10 } }, + /* 26 */ { { CHAR_B, 1<<12 }, { CHAR_G, 1<<9 } }, + /* 27 */ { { CHAR_H, 1<<3 }, { CHAR_I, 1<<0 } }, + /* 28 */ { { CHAR_F, 1<<8 }, { CHAR_J, 1<<7 } }, + /* 29 */ { { CHAR_E, 1<<6 }, { CHAR_C, 1<<10 } }, + /* 30 */ { { CHAR_D, 1<<4 }, { CHAR_A, 1<<5 } }, + /* 31 */ { { CHAR_I, 1<<4 }, { CHAR_F, 1<<7 } }, + /* 32 */ { { CHAR_H, 1<<11 }, { CHAR_B, 1<<9 } }, + /* 33 */ { { CHAR_G, 1<<0 }, { CHAR_J, 1<<6 } }, + /* 34 */ { { CHAR_A, 1<<6 }, { CHAR_E, 1<<8 } }, + /* 35 */ { { CHAR_C, 1<<1 }, { CHAR_D, 1<<2 } }, + /* 36 */ { { CHAR_F, 1<<9 }, { CHAR_I, 1<<12 } }, + /* 37 */ { { CHAR_E, 1<<11 }, { CHAR_G, 1<<1 } }, + /* 38 */ { { CHAR_J, 1<<5 }, { CHAR_H, 1<<4 } }, + /* 39 */ { { CHAR_D, 1<<3 }, { CHAR_B, 1<<2 } }, + /* 40 */ { { CHAR_A, 1<<7 }, { CHAR_C, 1<<0 } }, + /* 41 */ { { CHAR_B, 1<<3 }, { CHAR_E, 1<<1 } }, + /* 42 */ { { CHAR_G, 1<<10 }, { CHAR_D, 1<<5 } }, + /* 43 */ { { CHAR_I, 1<<7 }, { CHAR_J, 1<<4 } }, + /* 44 */ { { CHAR_C, 1<<11 }, { CHAR_F, 1<<6 } }, + /* 45 */ { { CHAR_A, 1<<8 }, { CHAR_H, 1<<12 } }, + /* 46 */ { { CHAR_E, 1<<2 }, { CHAR_I, 1<<1 } }, + /* 47 */ { { CHAR_F, 1<<10 }, { CHAR_D, 1<<0 } }, + /* 48 */ { { CHAR_J, 1<<3 }, { CHAR_A, 1<<9 } }, + /* 49 */ { { CHAR_G, 1<<5 }, { CHAR_C, 1<<4 } }, + /* 50 */ { { CHAR_H, 1<<8 }, { CHAR_B, 1<<7 } }, + /* 51 */ { { CHAR_F, 1<<0 }, { CHAR_E, 1<<5 } }, + /* 52 */ { { CHAR_C, 1<<3 }, { CHAR_A, 1<<10 } }, + /* 53 */ { { CHAR_G, 1<<12 }, { CHAR_J, 1<<2 } }, + /* 54 */ { { CHAR_D, 1<<11 }, { CHAR_B, 1<<6 } }, + /* 55 */ { { CHAR_I, 1<<8 }, { CHAR_H, 1<<9 } }, + /* 56 */ { { CHAR_F, 1<<4 }, { CHAR_A, 1<<11 } }, + /* 57 */ { { CHAR_B, 1<<5 }, { CHAR_C, 1<<2 } }, + /* 58 */ { { CHAR_J, 1<<1 }, { CHAR_E, 1<<12 } }, + /* 59 */ { { CHAR_I, 1<<3 }, { CHAR_G, 1<<6 } }, + /* 60 */ { { CHAR_H, 1<<0 }, { CHAR_D, 1<<7 } }, + /* 61 */ { { CHAR_E, 1<<7 }, { CHAR_H, 1<<5 } }, + /* 62 */ { { CHAR_A, 1<<12 }, { CHAR_B, 1<<11 } }, + /* 63 */ { { CHAR_C, 1<<9 }, { CHAR_J, 1<<0 } }, + /* 64 */ { { CHAR_G, 1<<8 }, { CHAR_F, 1<<3 } }, + /* 65 */ { { CHAR_D, 1<<10 }, { CHAR_I, 1<<2 } } +}; + +static gchar * tdaf_table[4] = { "T", "D", "A", "F" }; + +static guint character_table[] = { + /* Table I 5 of 13. */ + 31, 7936, 47, 7808, 55, 7552, 59, 7040, 61, 6016, + 62, 3968, 79, 7744, 87, 7488, 91, 6976, 93, 5952, + 94, 3904, 103, 7360, 107, 6848, 109, 5824, 110, 3776, + 115, 6592, 117, 5568, 118, 3520, 121, 5056, 122, 3008, + 124, 1984, 143, 7712, 151, 7456, 155, 6944, 157, 5920, + 158, 3872, 167, 7328, 171, 6816, 173, 5792, 174, 3744, + 179, 6560, 181, 5536, 182, 3488, 185, 5024, 186, 2976, + 188, 1952, 199, 7264, 203, 6752, 205, 5728, 206, 3680, + 211, 6496, 213, 5472, 214, 3424, 217, 4960, 218, 2912, + 220, 1888, 227, 6368, 229, 5344, 230, 3296, 233, 4832, + 234, 2784, 236, 1760, 241, 4576, 242, 2528, 244, 1504, + 248, 992, 271, 7696, 279, 7440, 283, 6928, 285, 5904, + 286, 3856, 295, 7312, 299, 6800, 301, 5776, 302, 3728, + 307, 6544, 309, 5520, 310, 3472, 313, 5008, 314, 2960, + 316, 1936, 327, 7248, 331, 6736, 333, 5712, 334, 3664, + 339, 6480, 341, 5456, 342, 3408, 345, 4944, 346, 2896, + 348, 1872, 355, 6352, 357, 5328, 358, 3280, 361, 4816, + 362, 2768, 364, 1744, 369, 4560, 370, 2512, 372, 1488, + 376, 976, 391, 7216, 395, 6704, 397, 5680, 398, 3632, + 403, 6448, 405, 5424, 406, 3376, 409, 4912, 410, 2864, + 412, 1840, 419, 6320, 421, 5296, 422, 3248, 425, 4784, + 426, 2736, 428, 1712, 433, 4528, 434, 2480, 436, 1456, + 440, 944, 451, 6256, 453, 5232, 454, 3184, 457, 4720, + 458, 2672, 460, 1648, 465, 4464, 466, 2416, 468, 1392, + 472, 880, 481, 4336, 482, 2288, 484, 1264, 488, 752, + 527, 7688, 535, 7432, 539, 6920, 541, 5896, 542, 3848, + 551, 7304, 555, 6792, 557, 5768, 558, 3720, 563, 6536, + 565, 5512, 566, 3464, 569, 5000, 570, 2952, 572, 1928, + 583, 7240, 587, 6728, 589, 5704, 590, 3656, 595, 6472, + 597, 5448, 598, 3400, 601, 4936, 602, 2888, 604, 1864, + 611, 6344, 613, 5320, 614, 3272, 617, 4808, 618, 2760, + 620, 1736, 625, 4552, 626, 2504, 628, 1480, 632, 968, + 647, 7208, 651, 6696, 653, 5672, 654, 3624, 659, 6440, + 661, 5416, 662, 3368, 665, 4904, 666, 2856, 668, 1832, + 675, 6312, 677, 5288, 678, 3240, 681, 4776, 682, 2728, + 684, 1704, 689, 4520, 690, 2472, 692, 1448, 696, 936, + 707, 6248, 709, 5224, 710, 3176, 713, 4712, 714, 2664, + 716, 1640, 721, 4456, 722, 2408, 724, 1384, 728, 872, + 737, 4328, 738, 2280, 740, 1256, 775, 7192, 779, 6680, + 781, 5656, 782, 3608, 787, 6424, 789, 5400, 790, 3352, + 793, 4888, 794, 2840, 796, 1816, 803, 6296, 805, 5272, + 806, 3224, 809, 4760, 810, 2712, 812, 1688, 817, 4504, + 818, 2456, 820, 1432, 824, 920, 835, 6232, 837, 5208, + 838, 3160, 841, 4696, 842, 2648, 844, 1624, 849, 4440, + 850, 2392, 852, 1368, 865, 4312, 866, 2264, 868, 1240, + 899, 6200, 901, 5176, 902, 3128, 905, 4664, 906, 2616, + 908, 1592, 913, 4408, 914, 2360, 916, 1336, 929, 4280, + 930, 2232, 932, 1208, 961, 4216, 962, 2168, 964, 1144, + 1039, 7684, 1047, 7428, 1051, 6916, 1053, 5892, 1054, 3844, + 1063, 7300, 1067, 6788, 1069, 5764, 1070, 3716, 1075, 6532, + 1077, 5508, 1078, 3460, 1081, 4996, 1082, 2948, 1084, 1924, + 1095, 7236, 1099, 6724, 1101, 5700, 1102, 3652, 1107, 6468, + 1109, 5444, 1110, 3396, 1113, 4932, 1114, 2884, 1116, 1860, + 1123, 6340, 1125, 5316, 1126, 3268, 1129, 4804, 1130, 2756, + 1132, 1732, 1137, 4548, 1138, 2500, 1140, 1476, 1159, 7204, + 1163, 6692, 1165, 5668, 1166, 3620, 1171, 6436, 1173, 5412, + 1174, 3364, 1177, 4900, 1178, 2852, 1180, 1828, 1187, 6308, + 1189, 5284, 1190, 3236, 1193, 4772, 1194, 2724, 1196, 1700, + 1201, 4516, 1202, 2468, 1204, 1444, 1219, 6244, 1221, 5220, + 1222, 3172, 1225, 4708, 1226, 2660, 1228, 1636, 1233, 4452, + 1234, 2404, 1236, 1380, 1249, 4324, 1250, 2276, 1287, 7188, + 1291, 6676, 1293, 5652, 1294, 3604, 1299, 6420, 1301, 5396, + 1302, 3348, 1305, 4884, 1306, 2836, 1308, 1812, 1315, 6292, + 1317, 5268, 1318, 3220, 1321, 4756, 1322, 2708, 1324, 1684, + 1329, 4500, 1330, 2452, 1332, 1428, 1347, 6228, 1349, 5204, + 1350, 3156, 1353, 4692, 1354, 2644, 1356, 1620, 1361, 4436, + 1362, 2388, 1377, 4308, 1378, 2260, 1411, 6196, 1413, 5172, + 1414, 3124, 1417, 4660, 1418, 2612, 1420, 1588, 1425, 4404, + 1426, 2356, 1441, 4276, 1442, 2228, 1473, 4212, 1474, 2164, + 1543, 7180, 1547, 6668, 1549, 5644, 1550, 3596, 1555, 6412, + 1557, 5388, 1558, 3340, 1561, 4876, 1562, 2828, 1564, 1804, + 1571, 6284, 1573, 5260, 1574, 3212, 1577, 4748, 1578, 2700, + 1580, 1676, 1585, 4492, 1586, 2444, 1603, 6220, 1605, 5196, + 1606, 3148, 1609, 4684, 1610, 2636, 1617, 4428, 1618, 2380, + 1633, 4300, 1634, 2252, 1667, 6188, 1669, 5164, 1670, 3116, + 1673, 4652, 1674, 2604, 1681, 4396, 1682, 2348, 1697, 4268, + 1698, 2220, 1729, 4204, 1730, 2156, 1795, 6172, 1797, 5148, + 1798, 3100, 1801, 4636, 1802, 2588, 1809, 4380, 1810, 2332, + 1825, 4252, 1826, 2204, 1857, 4188, 1858, 2140, 1921, 4156, + 1922, 2108, 2063, 7682, 2071, 7426, 2075, 6914, 2077, 5890, + 2078, 3842, 2087, 7298, 2091, 6786, 2093, 5762, 2094, 3714, + 2099, 6530, 2101, 5506, 2102, 3458, 2105, 4994, 2106, 2946, + 2119, 7234, 2123, 6722, 2125, 5698, 2126, 3650, 2131, 6466, + 2133, 5442, 2134, 3394, 2137, 4930, 2138, 2882, 2147, 6338, + 2149, 5314, 2150, 3266, 2153, 4802, 2154, 2754, 2161, 4546, + 2162, 2498, 2183, 7202, 2187, 6690, 2189, 5666, 2190, 3618, + 2195, 6434, 2197, 5410, 2198, 3362, 2201, 4898, 2202, 2850, + 2211, 6306, 2213, 5282, 2214, 3234, 2217, 4770, 2218, 2722, + 2225, 4514, 2226, 2466, 2243, 6242, 2245, 5218, 2246, 3170, + 2249, 4706, 2250, 2658, 2257, 4450, 2258, 2402, 2273, 4322, + 2311, 7186, 2315, 6674, 2317, 5650, 2318, 3602, 2323, 6418, + 2325, 5394, 2326, 3346, 2329, 4882, 2330, 2834, 2339, 6290, + 2341, 5266, 2342, 3218, 2345, 4754, 2346, 2706, 2353, 4498, + 2354, 2450, 2371, 6226, 2373, 5202, 2374, 3154, 2377, 4690, + 2378, 2642, 2385, 4434, 2401, 4306, 2435, 6194, 2437, 5170, + 2438, 3122, 2441, 4658, 2442, 2610, 2449, 4402, 2465, 4274, + 2497, 4210, 2567, 7178, 2571, 6666, 2573, 5642, 2574, 3594, + 2579, 6410, 2581, 5386, 2582, 3338, 2585, 4874, 2586, 2826, + 2595, 6282, 2597, 5258, 2598, 3210, 2601, 4746, 2602, 2698, + 2609, 4490, 2627, 6218, 2629, 5194, 2630, 3146, 2633, 4682, + 2641, 4426, 2657, 4298, 2691, 6186, 2693, 5162, 2694, 3114, + 2697, 4650, 2705, 4394, 2721, 4266, 2753, 4202, 2819, 6170, + 2821, 5146, 2822, 3098, 2825, 4634, 2833, 4378, 2849, 4250, + 2881, 4186, 2945, 4154, 3079, 7174, 3083, 6662, 3085, 5638, + 3086, 3590, 3091, 6406, 3093, 5382, 3094, 3334, 3097, 4870, + 3107, 6278, 3109, 5254, 3110, 3206, 3113, 4742, 3121, 4486, + 3139, 6214, 3141, 5190, 3145, 4678, 3153, 4422, 3169, 4294, + 3203, 6182, 3205, 5158, 3209, 4646, 3217, 4390, 3233, 4262, + 3265, 4198, 3331, 6166, 3333, 5142, 3337, 4630, 3345, 4374, + 3361, 4246, 3393, 4182, 3457, 4150, 3587, 6158, 3589, 5134, + 3593, 4622, 3601, 4366, 3617, 4238, 3649, 4174, 3713, 4142, + 3841, 4126, 4111, 7681, 4119, 7425, 4123, 6913, 4125, 5889, + 4135, 7297, 4139, 6785, 4141, 5761, 4147, 6529, 4149, 5505, + 4153, 4993, 4167, 7233, 4171, 6721, 4173, 5697, 4179, 6465, + 4181, 5441, 4185, 4929, 4195, 6337, 4197, 5313, 4201, 4801, + 4209, 4545, 4231, 7201, 4235, 6689, 4237, 5665, 4243, 6433, + 4245, 5409, 4249, 4897, 4259, 6305, 4261, 5281, 4265, 4769, + 4273, 4513, 4291, 6241, 4293, 5217, 4297, 4705, 4305, 4449, + 4359, 7185, 4363, 6673, 4365, 5649, 4371, 6417, 4373, 5393, + 4377, 4881, 4387, 6289, 4389, 5265, 4393, 4753, 4401, 4497, + 4419, 6225, 4421, 5201, 4425, 4689, 4483, 6193, 4485, 5169, + 4489, 4657, 4615, 7177, 4619, 6665, 4621, 5641, 4627, 6409, + 4629, 5385, 4633, 4873, 4643, 6281, 4645, 5257, 4649, 4745, + 4675, 6217, 4677, 5193, 4739, 6185, 4741, 5161, 4867, 6169, + 4869, 5145, 5127, 7173, 5131, 6661, 5133, 5637, 5139, 6405, + 5141, 5381, 5155, 6277, 5157, 5253, 5187, 6213, 5251, 6181, + 5379, 6165, 5635, 6157, 6151, 7171, 6155, 6659, 6163, 6403, + 6179, 6275, 6211, 5189, 4681, 4433, 4321, 3142, 2634, 2386, + 2274, 1612, 1364, 1252, 856, 744, 496, + /* Table II 2 of 13. */ + 3, 6144, 5, 5120, 6, 3072, 9, 4608, 10, 2560, + 12, 1536, 17, 4352, 18, 2304, 20, 1280, 24, 768, + 33, 4224, 34, 2176, 36, 1152, 40, 640, 48, 384, + 65, 4160, 66, 2112, 68, 1088, 72, 576, 80, 320, + 96, 192, 129, 4128, 130, 2080, 132, 1056, 136, 544, + 144, 288, 257, 4112, 258, 2064, 260, 1040, 264, 528, + 513, 4104, 514, 2056, 516, 1032, 1025, 4100, 1026, 2052, + 2049, 4098, 4097, 2050, 1028, 520, 272, 160 +}; + + + + +/*===========================================*/ +/* Local function prototypes */ +/*===========================================*/ +static gboolean is_string_valid (const gchar *data); + +static gchar *onecode_encode (const gchar *data); + +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 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. */ +/****************************************************************************/ +lglBarcode * +lgl_barcode_onecode_new (lglBarcodeType type, + gboolean text_flag, + gboolean checksum_flag, + gdouble w, + gdouble h, + const gchar *data) +{ + 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_encode (data); + if (code == NULL) { + return NULL; + } + + /* Now vectorize encoded data. */ + bc = onecode_vectorize (code); + + g_free (code); + + return bc; +} + + +/*--------------------------------------------------------------------------*/ +/* PRIVATE. Generate string of symbols, representing barcode. */ +/*--------------------------------------------------------------------------*/ +static gchar * +onecode_encode (const gchar *data) +{ + Int104 value = {{0}}; + gint i; + guint crc11; + guint codeword[10]; + guint character[10]; + gint d, a; + GString *code; + + if ( !is_string_valid (data) ) + { + return NULL; + } + + + /*-----------------------------------------------------------*/ + /* Step 1 -- Conversion of Data Fields into Binary Data */ + /*-----------------------------------------------------------*/ + + /* Step 1.a -- Routing Code */ + for ( i = 20; data[i] != 0; i++ ) + { + int104_mult_uint (&value, 10); + int104_add_uint (&value, data[i] - '0'); + } + switch ( i-20 ) + { + case 0: + break; + case 5: + int104_add_uint (&value, 1); + break; + case 9: + int104_add_uint (&value, 1); + int104_add_uint (&value, 100000); + break; + case 11: + int104_add_uint (&value, 1); + int104_add_uint (&value, 100000); + int104_add_uint64 (&value, 1000000000); + break; + default: + return NULL; /* Should not happen if length tests passed. */ + break; + } + + /* Step 1.b -- Tracking Code */ + int104_mult_uint (&value, 10); + int104_add_uint (&value, data[0] - '0'); + int104_mult_uint (&value, 5); + int104_add_uint (&value, data[1] - '0'); + + for ( i = 2; i < 20; i++ ) + { + int104_mult_uint (&value, 10); + int104_add_uint (&value, data[i] - '0'); + } + + + /*-----------------------------------------------------------*/ + /* Step 2 -- Generation of 11-Bit CRC on Binary Data */ + /*-----------------------------------------------------------*/ + + crc11 = USPS_MSB_Math_CRC11GenerateFrameCheckSequence( value.byte ); + + + /*-----------------------------------------------------------*/ + /* Step 3 -- Conversion of Binary Data to Codewords */ + /*-----------------------------------------------------------*/ + + codeword[9] = int104_div_uint (&value, 636); + for ( i = 8; i >= 1; i-- ) + { + codeword[i] = int104_div_uint (&value, 1365); + } + codeword[0] = int104_div_uint (&value, 659); + + + /*-----------------------------------------------------------*/ + /* Step 4 -- Inserting Additional Information into Codewords */ + /*-----------------------------------------------------------*/ + + codeword[9] *= 2; + codeword[0] += (crc11 & 0x400) ? 659 : 0; + + + /*-----------------------------------------------------------*/ + /* Step 5 -- Conversion from Codewords to Characters */ + /*-----------------------------------------------------------*/ + + for ( i = 0; i < 10; i++ ) + { + character[i] = character_table[ codeword[i] ]; + + if ( crc11 & (1< '4') + { + return FALSE; /* Invalid Barcode Identifier. */ + } + + return TRUE; +} + + +/*--------------------------------------------------------------------------*/ +/* Multiply 104 bit integer by unsigned int. */ +/*--------------------------------------------------------------------------*/ +static void +int104_mult_uint (Int104 *x, + guint y) +{ + gint i; + guint64 temp, carry; + + carry = 0; + for ( i = 12; i >= 0; i-- ) + { + temp = x->byte[i] * y + carry; + + x->byte[i] = temp & 0xFF; + carry = temp >> 8; + } +} + + +/*--------------------------------------------------------------------------*/ +/* Add unsigned int to 104 bit integer. */ +/*--------------------------------------------------------------------------*/ +static void +int104_add_uint (Int104 *x, + guint y) +{ + gint i; + guint temp, carry; + + carry = 0; + for ( i = 12; i >= 0; i-- ) + { + temp = x->byte[i] + (y & 0xFF) + carry; + + x->byte[i] = temp & 0xFF; + carry = temp >> 8; + y = y >> 8; + } +} + + +/*--------------------------------------------------------------------------*/ +/* Add unsigned 64 bit integer to 104 bit integer. */ +/*--------------------------------------------------------------------------*/ +static void +int104_add_uint64 (Int104 *x, + guint64 y) +{ + gint i; + guint64 temp, carry; + + carry = 0; + for ( i = 12; i >= 0; i-- ) + { + temp = x->byte[i] + (y & 0xFF) + carry; + + x->byte[i] = temp & 0xFF; + carry = temp >> 8; + y = y >> 8; + } +} + + +/*--------------------------------------------------------------------------*/ +/* Divide 104 bit integer by unsigned int. */ +/*--------------------------------------------------------------------------*/ +static guint +int104_div_uint (Int104 *x, + guint y) +{ + guint carry, tmp, i; + + carry = 0; + for ( i = 0; i < 13; i++ ) + { + tmp = x->byte[i] + (carry<<8); + x->byte[i] = tmp / y; + carry = tmp % y; + } + + return carry; +} + + +/*--------------------------------------------------------------------------*/ +/* Print hex representation of 104 bit integer. (For debugging) */ +/*--------------------------------------------------------------------------*/ +#ifdef DEBUG +static void +int104_print (Int104 *x) +{ + gint i; + + for ( i = 0; i < 13; i++ ) + { + g_print ("%02x ", x->byte[i] & 0xFF); + } + g_print ("\n"); +} +#endif + + +/*************************************************************************** + ** USPS_MSB_Math_CRC11GenerateFrameCheckSequence + ** + ** Inputs: + ** ByteAttayPtr is the address of a 13 byte array holding 102 bytes which + ** are right justified - ie: the leftmost 2 bits of the first byte do not + ** hold data and must be set to zero. + ** + ** Outputs: + ** return unsigned short - 11 bit Frame Check Sequence (right justified) + ** + ** From Appendix C of USPS publication USPS-B-3200E, 07/08/05. + ***************************************************************************/ +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 ) + { + FrameCheckSequence = (FrameCheckSequence << 1) ^ GeneratorPolynomial; + } + else + { + 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 = (FrameCheckSequence << 1) ^ GeneratorPolynomial; + } + else + { + 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; +} + + + + +/* + * 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-onecode.h b/libglbarcode/lgl-barcode-onecode.h new file mode 100644 index 00000000..f7465eea --- /dev/null +++ b/libglbarcode/lgl-barcode-onecode.h @@ -0,0 +1,49 @@ +/* + * lgl-barcode-onecode.h + * Copyright (C) 2010 Jim Evins . + * + * 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 . + */ + +#ifndef __LGL_BARCODE_ONECODE_H__ +#define __LGL_BARCODE_ONECODE_H__ + +#include "lgl-barcode.h" +#include "lgl-barcode-type.h" + +G_BEGIN_DECLS + +lglBarcode *lgl_barcode_onecode_new (lglBarcodeType type, + gboolean text_flag, + gboolean checksum_flag, + gdouble w, + gdouble h, + const gchar *data); + +G_END_DECLS + +#endif /* __LGL_BARCODE_ONECODE_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/lgl-barcode-postnet.c b/libglbarcode/lgl-barcode-postnet.c new file mode 100644 index 00000000..96b4132e --- /dev/null +++ b/libglbarcode/lgl-barcode-postnet.c @@ -0,0 +1,272 @@ +/* + * lgl-barcode-postnet.c + * Copyright (C) 2001-2010 Jim Evins . + * + * 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 . + */ + +/* + * This module implements the POSTNET barcode specified in the USPS + * publication 25, Mar 2001. + */ + +#include + +#include "lgl-barcode-postnet.h" + +#include +#include + + +/*========================================================*/ +/* 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/libglbarcode/lgl-barcode-postnet.h b/libglbarcode/lgl-barcode-postnet.h new file mode 100644 index 00000000..3d084779 --- /dev/null +++ b/libglbarcode/lgl-barcode-postnet.h @@ -0,0 +1,49 @@ +/* + * lgl-barcode-postnet.h + * Copyright (C) 2001-2010 Jim Evins . + * + * 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 . + */ + +#ifndef __LGL_BARCODE_POSTNET_H__ +#define __LGL_BARCODE_POSTNET_H__ + +#include "lgl-barcode.h" +#include "lgl-barcode-type.h" + +G_BEGIN_DECLS + +lglBarcode *lgl_barcode_postnet_new (lglBarcodeType type, + gboolean text_flag, + gboolean checksum_flag, + gdouble w, + gdouble h, + const gchar *data); + +G_END_DECLS + +#endif /* __LGL_BARCODE_POSTNET_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/lgl-barcode-render-to-cairo.c b/libglbarcode/lgl-barcode-render-to-cairo.c new file mode 100644 index 00000000..6cb84b35 --- /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 . + * + * 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 . + */ + +#include + +#include "lgl-barcode-render-to-cairo.h" + +#include +#include + + +/*===========================================*/ +/* 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/libglbarcode/lgl-barcode-render-to-cairo.h b/libglbarcode/lgl-barcode-render-to-cairo.h new file mode 100644 index 00000000..3ad67ad1 --- /dev/null +++ b/libglbarcode/lgl-barcode-render-to-cairo.h @@ -0,0 +1,45 @@ +/* + * lgl-barcode-render-to-cairo.h + * Copyright (C) 2010 Jim Evins . + * + * 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 . + */ + +#ifndef __LGL_RENDER_TO_CAIRO_H__ +#define __LGL_RENDER_TO_CAIRO_H__ + +#include "lgl-barcode.h" +#include + +G_BEGIN_DECLS + +void lgl_barcode_render_to_cairo (const lglBarcode *bc, + cairo_t *cr); + +G_END_DECLS + +#endif /* __LGL_RENDER_TO_CAIRO_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/lgl-barcode-type.h b/libglbarcode/lgl-barcode-type.h new file mode 100644 index 00000000..43634d7a --- /dev/null +++ b/libglbarcode/lgl-barcode-type.h @@ -0,0 +1,58 @@ +/* + * lgl-barcode-type.h + * Copyright (C) 2001-2010 Jim Evins . + * + * 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 . + */ + +#ifndef __LGL_BARCODE_TYPE_H__ +#define __LGL_BARCODE_TYPE_H__ + +#include + +G_BEGIN_DECLS + + +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 /* __LGL_BARCODE_TYPE_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/lgl-barcode.c b/libglbarcode/lgl-barcode.c new file mode 100644 index 00000000..25409d82 --- /dev/null +++ b/libglbarcode/lgl-barcode.c @@ -0,0 +1,257 @@ +/* + * lgl-barcode.c + * Copyright (C) 2001-2010 Jim Evins . + * + * 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 . + */ + +#include + +#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 00000000..f7f9a072 --- /dev/null +++ b/libglbarcode/lgl-barcode.h @@ -0,0 +1,317 @@ +/* + * lgl-barcode.h + * Copyright (C) 2001-2010 Jim Evins . + * + * 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 . + */ + +#ifndef __LGL_BARCODE_H__ +#define __LGL_BARCODE_H__ + +#include + +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 00000000..bdcbf6d4 --- /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/libglbarcode/libglbarcode.h b/libglbarcode/libglbarcode.h new file mode 100644 index 00000000..bad41ee7 --- /dev/null +++ b/libglbarcode/libglbarcode.h @@ -0,0 +1,46 @@ +/* + * libglbarcode.h + * Copyright (C) 2010 Jim Evins . + * + * 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 . + */ + +#ifndef __LIBGLBARCODE_H__ +#define __LIBGLBARCODE_H__ + + +#include +#include +#include + +#include + +#include +#include + + +#endif /* __LIBGLBARCODE_H__ */ + + + +/* + * Local Variables: -- emacs + * mode: C -- emacs + * c-basic-offset: 8 -- emacs + * tab-width: 8 -- emacs + * indent-tabs-mode: nil -- emacs + * End: -- emacs + */ diff --git a/src/Makefile.am b/src/Makefile.am index 77f42090..fb94449d 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 3f69684c..9f9904e2 100644 --- a/src/bc-backends.c +++ b/src/bc-backends.c @@ -25,8 +25,7 @@ #include #include -#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 1cd2b122..8ed764db 100644 --- a/src/bc-backends.h +++ b/src/bc-backends.h @@ -22,7 +22,7 @@ #define __BC_BACKENDS_H__ #include -#include "bc.h" +#include 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 00000000..e50ebc8e --- /dev/null +++ b/src/bc-builtin.c @@ -0,0 +1,97 @@ +/* + * bc-builtin.c + * Copyright (C) 2001-2009 Jim Evins . + * + * 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 . + */ + +/* + * This module implements the BUILTIN barcode specified in the USPS + * publication 25, Mar 2001. + */ + +#include + +#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-builtin.h b/src/bc-builtin.h new file mode 100644 index 00000000..459b4132 --- /dev/null +++ b/src/bc-builtin.h @@ -0,0 +1,49 @@ +/* + * bc-builtin.h + * Copyright (C) 2001-2009 Jim Evins . + * + * 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 . + */ + +#ifndef __BC_BUILTIN_H__ +#define __BC_BUILTIN_H__ + +#include + + +G_BEGIN_DECLS + +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_BUILTIN_H__ */ + + + +/* + * Local Variables: -- emacs + * mode: C -- emacs + * c-basic-offset: 8 -- emacs + * tab-width: 8 -- emacs + * indent-tabs-mode: nil -- emacs + * End: -- emacs + */ diff --git a/src/bc-gnubarcode.c b/src/bc-gnubarcode.c index 327b02f1..88b9e280 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 ac96b346..6441a48b 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 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 dbd06ecb..0719ed5d 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 64655b0b..8695408c 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 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 02373526..396b55bc 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 2c3e7eeb..99d3c3d5 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 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-onecode.c b/src/bc-onecode.c deleted file mode 100644 index d62460a8..00000000 --- a/src/bc-onecode.c +++ /dev/null @@ -1,725 +0,0 @@ -/* - * bc-onecode.c - * Copyright (C) 2010 Jim Evins . - * - * 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 . - */ - -/* - * This module implements the Intelligent Mail (OneCode) barcode - * specified in the USPS specification USPS-B-3200E, 07/08/05. - */ - -#include - -#include "bc-onecode.h" - -#include -#include -#include - -#include "debug.h" - - -/*========================================================*/ -/* Private macros and constants. */ -/*========================================================*/ - -#define CHAR_A 0 -#define CHAR_B 1 -#define CHAR_C 2 -#define CHAR_D 3 -#define CHAR_E 4 -#define CHAR_F 5 -#define CHAR_G 6 -#define CHAR_H 7 -#define CHAR_I 8 -#define CHAR_J 9 - -#define PTS_PER_INCH 72.0 - -#define ONECODE_BAR_WIDTH ( 0.02 * PTS_PER_INCH ) -#define ONECODE_FULL_HEIGHT ( 0.145 * PTS_PER_INCH ) -#define ONECODE_ASCENDER_HEIGHT ( 0.0965 * PTS_PER_INCH ) -#define ONECODE_DESCENDER_HEIGHT ( 0.0965 * PTS_PER_INCH ) -#define ONECODE_TRACKER_HEIGHT ( 0.048 * PTS_PER_INCH ) -#define ONECODE_FULL_OFFSET 0 -#define ONECODE_ASCENDER_OFFSET 0 -#define ONECODE_DESCENDER_OFFSET ( 0.0485 * PTS_PER_INCH ) -#define ONECODE_TRACKER_OFFSET ( 0.0485 * PTS_PER_INCH ) -#define ONECODE_BAR_PITCH ( 0.0458 * PTS_PER_INCH ) -#define ONECODE_HORIZ_MARGIN ( 0.125 * PTS_PER_INCH ) -#define ONECODE_VERT_MARGIN ( 0.028 * PTS_PER_INCH ) - - -/*========================================================*/ -/* Private types. */ -/*========================================================*/ - -typedef struct { - guchar byte[13]; -} Int104; - -typedef struct { - struct { gint i; gint mask; } descender; - struct { gint i; gint mask; } ascender; -} BarMapEntry; - - -/*===========================================*/ -/* Private globals */ -/*===========================================*/ - -static BarMapEntry bar_map[] = { - /* 1 */ { { CHAR_H, 1<<2 }, { CHAR_E, 1<<3 } }, - /* 2 */ { { CHAR_B, 1<<10 }, { CHAR_A, 1<<0 } }, - /* 3 */ { { CHAR_J, 1<<12 }, { CHAR_C, 1<<8 } }, - /* 4 */ { { CHAR_F, 1<<5 }, { CHAR_G, 1<<11 } }, - /* 5 */ { { CHAR_I, 1<<9 }, { CHAR_D, 1<<1 } }, - /* 6 */ { { CHAR_A, 1<<1 }, { CHAR_F, 1<<12 } }, - /* 7 */ { { CHAR_C, 1<<5 }, { CHAR_B, 1<<8 } }, - /* 8 */ { { CHAR_E, 1<<4 }, { CHAR_J, 1<<11 } }, - /* 9 */ { { CHAR_G, 1<<3 }, { CHAR_I, 1<<10 } }, - /* 10 */ { { CHAR_D, 1<<9 }, { CHAR_H, 1<<6 } }, - /* 11 */ { { CHAR_F, 1<<11 }, { CHAR_B, 1<<4 } }, - /* 12 */ { { CHAR_I, 1<<5 }, { CHAR_C, 1<<12 } }, - /* 13 */ { { CHAR_J, 1<<10 }, { CHAR_A, 1<<2 } }, - /* 14 */ { { CHAR_H, 1<<1 }, { CHAR_G, 1<<7 } }, - /* 15 */ { { CHAR_D, 1<<6 }, { CHAR_E, 1<<9 } }, - /* 16 */ { { CHAR_A, 1<<3 }, { CHAR_I, 1<<6 } }, - /* 17 */ { { CHAR_G, 1<<4 }, { CHAR_C, 1<<7 } }, - /* 18 */ { { CHAR_B, 1<<1 }, { CHAR_J, 1<<9 } }, - /* 19 */ { { CHAR_H, 1<<10 }, { CHAR_F, 1<<2 } }, - /* 20 */ { { CHAR_E, 1<<0 }, { CHAR_D, 1<<8 } }, - /* 21 */ { { CHAR_G, 1<<2 }, { CHAR_A, 1<<4 } }, - /* 22 */ { { CHAR_I, 1<<11 }, { CHAR_B, 1<<0 } }, - /* 23 */ { { CHAR_J, 1<<8 }, { CHAR_D, 1<<12 } }, - /* 24 */ { { CHAR_C, 1<<6 }, { CHAR_H, 1<<7 } }, - /* 25 */ { { CHAR_F, 1<<1 }, { CHAR_E, 1<<10 } }, - /* 26 */ { { CHAR_B, 1<<12 }, { CHAR_G, 1<<9 } }, - /* 27 */ { { CHAR_H, 1<<3 }, { CHAR_I, 1<<0 } }, - /* 28 */ { { CHAR_F, 1<<8 }, { CHAR_J, 1<<7 } }, - /* 29 */ { { CHAR_E, 1<<6 }, { CHAR_C, 1<<10 } }, - /* 30 */ { { CHAR_D, 1<<4 }, { CHAR_A, 1<<5 } }, - /* 31 */ { { CHAR_I, 1<<4 }, { CHAR_F, 1<<7 } }, - /* 32 */ { { CHAR_H, 1<<11 }, { CHAR_B, 1<<9 } }, - /* 33 */ { { CHAR_G, 1<<0 }, { CHAR_J, 1<<6 } }, - /* 34 */ { { CHAR_A, 1<<6 }, { CHAR_E, 1<<8 } }, - /* 35 */ { { CHAR_C, 1<<1 }, { CHAR_D, 1<<2 } }, - /* 36 */ { { CHAR_F, 1<<9 }, { CHAR_I, 1<<12 } }, - /* 37 */ { { CHAR_E, 1<<11 }, { CHAR_G, 1<<1 } }, - /* 38 */ { { CHAR_J, 1<<5 }, { CHAR_H, 1<<4 } }, - /* 39 */ { { CHAR_D, 1<<3 }, { CHAR_B, 1<<2 } }, - /* 40 */ { { CHAR_A, 1<<7 }, { CHAR_C, 1<<0 } }, - /* 41 */ { { CHAR_B, 1<<3 }, { CHAR_E, 1<<1 } }, - /* 42 */ { { CHAR_G, 1<<10 }, { CHAR_D, 1<<5 } }, - /* 43 */ { { CHAR_I, 1<<7 }, { CHAR_J, 1<<4 } }, - /* 44 */ { { CHAR_C, 1<<11 }, { CHAR_F, 1<<6 } }, - /* 45 */ { { CHAR_A, 1<<8 }, { CHAR_H, 1<<12 } }, - /* 46 */ { { CHAR_E, 1<<2 }, { CHAR_I, 1<<1 } }, - /* 47 */ { { CHAR_F, 1<<10 }, { CHAR_D, 1<<0 } }, - /* 48 */ { { CHAR_J, 1<<3 }, { CHAR_A, 1<<9 } }, - /* 49 */ { { CHAR_G, 1<<5 }, { CHAR_C, 1<<4 } }, - /* 50 */ { { CHAR_H, 1<<8 }, { CHAR_B, 1<<7 } }, - /* 51 */ { { CHAR_F, 1<<0 }, { CHAR_E, 1<<5 } }, - /* 52 */ { { CHAR_C, 1<<3 }, { CHAR_A, 1<<10 } }, - /* 53 */ { { CHAR_G, 1<<12 }, { CHAR_J, 1<<2 } }, - /* 54 */ { { CHAR_D, 1<<11 }, { CHAR_B, 1<<6 } }, - /* 55 */ { { CHAR_I, 1<<8 }, { CHAR_H, 1<<9 } }, - /* 56 */ { { CHAR_F, 1<<4 }, { CHAR_A, 1<<11 } }, - /* 57 */ { { CHAR_B, 1<<5 }, { CHAR_C, 1<<2 } }, - /* 58 */ { { CHAR_J, 1<<1 }, { CHAR_E, 1<<12 } }, - /* 59 */ { { CHAR_I, 1<<3 }, { CHAR_G, 1<<6 } }, - /* 60 */ { { CHAR_H, 1<<0 }, { CHAR_D, 1<<7 } }, - /* 61 */ { { CHAR_E, 1<<7 }, { CHAR_H, 1<<5 } }, - /* 62 */ { { CHAR_A, 1<<12 }, { CHAR_B, 1<<11 } }, - /* 63 */ { { CHAR_C, 1<<9 }, { CHAR_J, 1<<0 } }, - /* 64 */ { { CHAR_G, 1<<8 }, { CHAR_F, 1<<3 } }, - /* 65 */ { { CHAR_D, 1<<10 }, { CHAR_I, 1<<2 } } -}; - -static gchar * tdaf_table[4] = { "T", "D", "A", "F" }; - -static guint character_table[] = { - /* Table I 5 of 13. */ - 31, 7936, 47, 7808, 55, 7552, 59, 7040, 61, 6016, - 62, 3968, 79, 7744, 87, 7488, 91, 6976, 93, 5952, - 94, 3904, 103, 7360, 107, 6848, 109, 5824, 110, 3776, - 115, 6592, 117, 5568, 118, 3520, 121, 5056, 122, 3008, - 124, 1984, 143, 7712, 151, 7456, 155, 6944, 157, 5920, - 158, 3872, 167, 7328, 171, 6816, 173, 5792, 174, 3744, - 179, 6560, 181, 5536, 182, 3488, 185, 5024, 186, 2976, - 188, 1952, 199, 7264, 203, 6752, 205, 5728, 206, 3680, - 211, 6496, 213, 5472, 214, 3424, 217, 4960, 218, 2912, - 220, 1888, 227, 6368, 229, 5344, 230, 3296, 233, 4832, - 234, 2784, 236, 1760, 241, 4576, 242, 2528, 244, 1504, - 248, 992, 271, 7696, 279, 7440, 283, 6928, 285, 5904, - 286, 3856, 295, 7312, 299, 6800, 301, 5776, 302, 3728, - 307, 6544, 309, 5520, 310, 3472, 313, 5008, 314, 2960, - 316, 1936, 327, 7248, 331, 6736, 333, 5712, 334, 3664, - 339, 6480, 341, 5456, 342, 3408, 345, 4944, 346, 2896, - 348, 1872, 355, 6352, 357, 5328, 358, 3280, 361, 4816, - 362, 2768, 364, 1744, 369, 4560, 370, 2512, 372, 1488, - 376, 976, 391, 7216, 395, 6704, 397, 5680, 398, 3632, - 403, 6448, 405, 5424, 406, 3376, 409, 4912, 410, 2864, - 412, 1840, 419, 6320, 421, 5296, 422, 3248, 425, 4784, - 426, 2736, 428, 1712, 433, 4528, 434, 2480, 436, 1456, - 440, 944, 451, 6256, 453, 5232, 454, 3184, 457, 4720, - 458, 2672, 460, 1648, 465, 4464, 466, 2416, 468, 1392, - 472, 880, 481, 4336, 482, 2288, 484, 1264, 488, 752, - 527, 7688, 535, 7432, 539, 6920, 541, 5896, 542, 3848, - 551, 7304, 555, 6792, 557, 5768, 558, 3720, 563, 6536, - 565, 5512, 566, 3464, 569, 5000, 570, 2952, 572, 1928, - 583, 7240, 587, 6728, 589, 5704, 590, 3656, 595, 6472, - 597, 5448, 598, 3400, 601, 4936, 602, 2888, 604, 1864, - 611, 6344, 613, 5320, 614, 3272, 617, 4808, 618, 2760, - 620, 1736, 625, 4552, 626, 2504, 628, 1480, 632, 968, - 647, 7208, 651, 6696, 653, 5672, 654, 3624, 659, 6440, - 661, 5416, 662, 3368, 665, 4904, 666, 2856, 668, 1832, - 675, 6312, 677, 5288, 678, 3240, 681, 4776, 682, 2728, - 684, 1704, 689, 4520, 690, 2472, 692, 1448, 696, 936, - 707, 6248, 709, 5224, 710, 3176, 713, 4712, 714, 2664, - 716, 1640, 721, 4456, 722, 2408, 724, 1384, 728, 872, - 737, 4328, 738, 2280, 740, 1256, 775, 7192, 779, 6680, - 781, 5656, 782, 3608, 787, 6424, 789, 5400, 790, 3352, - 793, 4888, 794, 2840, 796, 1816, 803, 6296, 805, 5272, - 806, 3224, 809, 4760, 810, 2712, 812, 1688, 817, 4504, - 818, 2456, 820, 1432, 824, 920, 835, 6232, 837, 5208, - 838, 3160, 841, 4696, 842, 2648, 844, 1624, 849, 4440, - 850, 2392, 852, 1368, 865, 4312, 866, 2264, 868, 1240, - 899, 6200, 901, 5176, 902, 3128, 905, 4664, 906, 2616, - 908, 1592, 913, 4408, 914, 2360, 916, 1336, 929, 4280, - 930, 2232, 932, 1208, 961, 4216, 962, 2168, 964, 1144, - 1039, 7684, 1047, 7428, 1051, 6916, 1053, 5892, 1054, 3844, - 1063, 7300, 1067, 6788, 1069, 5764, 1070, 3716, 1075, 6532, - 1077, 5508, 1078, 3460, 1081, 4996, 1082, 2948, 1084, 1924, - 1095, 7236, 1099, 6724, 1101, 5700, 1102, 3652, 1107, 6468, - 1109, 5444, 1110, 3396, 1113, 4932, 1114, 2884, 1116, 1860, - 1123, 6340, 1125, 5316, 1126, 3268, 1129, 4804, 1130, 2756, - 1132, 1732, 1137, 4548, 1138, 2500, 1140, 1476, 1159, 7204, - 1163, 6692, 1165, 5668, 1166, 3620, 1171, 6436, 1173, 5412, - 1174, 3364, 1177, 4900, 1178, 2852, 1180, 1828, 1187, 6308, - 1189, 5284, 1190, 3236, 1193, 4772, 1194, 2724, 1196, 1700, - 1201, 4516, 1202, 2468, 1204, 1444, 1219, 6244, 1221, 5220, - 1222, 3172, 1225, 4708, 1226, 2660, 1228, 1636, 1233, 4452, - 1234, 2404, 1236, 1380, 1249, 4324, 1250, 2276, 1287, 7188, - 1291, 6676, 1293, 5652, 1294, 3604, 1299, 6420, 1301, 5396, - 1302, 3348, 1305, 4884, 1306, 2836, 1308, 1812, 1315, 6292, - 1317, 5268, 1318, 3220, 1321, 4756, 1322, 2708, 1324, 1684, - 1329, 4500, 1330, 2452, 1332, 1428, 1347, 6228, 1349, 5204, - 1350, 3156, 1353, 4692, 1354, 2644, 1356, 1620, 1361, 4436, - 1362, 2388, 1377, 4308, 1378, 2260, 1411, 6196, 1413, 5172, - 1414, 3124, 1417, 4660, 1418, 2612, 1420, 1588, 1425, 4404, - 1426, 2356, 1441, 4276, 1442, 2228, 1473, 4212, 1474, 2164, - 1543, 7180, 1547, 6668, 1549, 5644, 1550, 3596, 1555, 6412, - 1557, 5388, 1558, 3340, 1561, 4876, 1562, 2828, 1564, 1804, - 1571, 6284, 1573, 5260, 1574, 3212, 1577, 4748, 1578, 2700, - 1580, 1676, 1585, 4492, 1586, 2444, 1603, 6220, 1605, 5196, - 1606, 3148, 1609, 4684, 1610, 2636, 1617, 4428, 1618, 2380, - 1633, 4300, 1634, 2252, 1667, 6188, 1669, 5164, 1670, 3116, - 1673, 4652, 1674, 2604, 1681, 4396, 1682, 2348, 1697, 4268, - 1698, 2220, 1729, 4204, 1730, 2156, 1795, 6172, 1797, 5148, - 1798, 3100, 1801, 4636, 1802, 2588, 1809, 4380, 1810, 2332, - 1825, 4252, 1826, 2204, 1857, 4188, 1858, 2140, 1921, 4156, - 1922, 2108, 2063, 7682, 2071, 7426, 2075, 6914, 2077, 5890, - 2078, 3842, 2087, 7298, 2091, 6786, 2093, 5762, 2094, 3714, - 2099, 6530, 2101, 5506, 2102, 3458, 2105, 4994, 2106, 2946, - 2119, 7234, 2123, 6722, 2125, 5698, 2126, 3650, 2131, 6466, - 2133, 5442, 2134, 3394, 2137, 4930, 2138, 2882, 2147, 6338, - 2149, 5314, 2150, 3266, 2153, 4802, 2154, 2754, 2161, 4546, - 2162, 2498, 2183, 7202, 2187, 6690, 2189, 5666, 2190, 3618, - 2195, 6434, 2197, 5410, 2198, 3362, 2201, 4898, 2202, 2850, - 2211, 6306, 2213, 5282, 2214, 3234, 2217, 4770, 2218, 2722, - 2225, 4514, 2226, 2466, 2243, 6242, 2245, 5218, 2246, 3170, - 2249, 4706, 2250, 2658, 2257, 4450, 2258, 2402, 2273, 4322, - 2311, 7186, 2315, 6674, 2317, 5650, 2318, 3602, 2323, 6418, - 2325, 5394, 2326, 3346, 2329, 4882, 2330, 2834, 2339, 6290, - 2341, 5266, 2342, 3218, 2345, 4754, 2346, 2706, 2353, 4498, - 2354, 2450, 2371, 6226, 2373, 5202, 2374, 3154, 2377, 4690, - 2378, 2642, 2385, 4434, 2401, 4306, 2435, 6194, 2437, 5170, - 2438, 3122, 2441, 4658, 2442, 2610, 2449, 4402, 2465, 4274, - 2497, 4210, 2567, 7178, 2571, 6666, 2573, 5642, 2574, 3594, - 2579, 6410, 2581, 5386, 2582, 3338, 2585, 4874, 2586, 2826, - 2595, 6282, 2597, 5258, 2598, 3210, 2601, 4746, 2602, 2698, - 2609, 4490, 2627, 6218, 2629, 5194, 2630, 3146, 2633, 4682, - 2641, 4426, 2657, 4298, 2691, 6186, 2693, 5162, 2694, 3114, - 2697, 4650, 2705, 4394, 2721, 4266, 2753, 4202, 2819, 6170, - 2821, 5146, 2822, 3098, 2825, 4634, 2833, 4378, 2849, 4250, - 2881, 4186, 2945, 4154, 3079, 7174, 3083, 6662, 3085, 5638, - 3086, 3590, 3091, 6406, 3093, 5382, 3094, 3334, 3097, 4870, - 3107, 6278, 3109, 5254, 3110, 3206, 3113, 4742, 3121, 4486, - 3139, 6214, 3141, 5190, 3145, 4678, 3153, 4422, 3169, 4294, - 3203, 6182, 3205, 5158, 3209, 4646, 3217, 4390, 3233, 4262, - 3265, 4198, 3331, 6166, 3333, 5142, 3337, 4630, 3345, 4374, - 3361, 4246, 3393, 4182, 3457, 4150, 3587, 6158, 3589, 5134, - 3593, 4622, 3601, 4366, 3617, 4238, 3649, 4174, 3713, 4142, - 3841, 4126, 4111, 7681, 4119, 7425, 4123, 6913, 4125, 5889, - 4135, 7297, 4139, 6785, 4141, 5761, 4147, 6529, 4149, 5505, - 4153, 4993, 4167, 7233, 4171, 6721, 4173, 5697, 4179, 6465, - 4181, 5441, 4185, 4929, 4195, 6337, 4197, 5313, 4201, 4801, - 4209, 4545, 4231, 7201, 4235, 6689, 4237, 5665, 4243, 6433, - 4245, 5409, 4249, 4897, 4259, 6305, 4261, 5281, 4265, 4769, - 4273, 4513, 4291, 6241, 4293, 5217, 4297, 4705, 4305, 4449, - 4359, 7185, 4363, 6673, 4365, 5649, 4371, 6417, 4373, 5393, - 4377, 4881, 4387, 6289, 4389, 5265, 4393, 4753, 4401, 4497, - 4419, 6225, 4421, 5201, 4425, 4689, 4483, 6193, 4485, 5169, - 4489, 4657, 4615, 7177, 4619, 6665, 4621, 5641, 4627, 6409, - 4629, 5385, 4633, 4873, 4643, 6281, 4645, 5257, 4649, 4745, - 4675, 6217, 4677, 5193, 4739, 6185, 4741, 5161, 4867, 6169, - 4869, 5145, 5127, 7173, 5131, 6661, 5133, 5637, 5139, 6405, - 5141, 5381, 5155, 6277, 5157, 5253, 5187, 6213, 5251, 6181, - 5379, 6165, 5635, 6157, 6151, 7171, 6155, 6659, 6163, 6403, - 6179, 6275, 6211, 5189, 4681, 4433, 4321, 3142, 2634, 2386, - 2274, 1612, 1364, 1252, 856, 744, 496, - /* Table II 2 of 13. */ - 3, 6144, 5, 5120, 6, 3072, 9, 4608, 10, 2560, - 12, 1536, 17, 4352, 18, 2304, 20, 1280, 24, 768, - 33, 4224, 34, 2176, 36, 1152, 40, 640, 48, 384, - 65, 4160, 66, 2112, 68, 1088, 72, 576, 80, 320, - 96, 192, 129, 4128, 130, 2080, 132, 1056, 136, 544, - 144, 288, 257, 4112, 258, 2064, 260, 1040, 264, 528, - 513, 4104, 514, 2056, 516, 1032, 1025, 4100, 1026, 2052, - 2049, 4098, 4097, 2050, 1028, 520, 272, 160 -}; - - - - -/*===========================================*/ -/* Local function prototypes */ -/*===========================================*/ -static gboolean is_string_valid (const gchar *digits); - -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); -static void int104_print (Int104 *x); - -unsigned short USPS_MSB_Math_CRC11GenerateFrameCheckSequence( unsigned char *ByteArrayPtr ); - - -/****************************************************************************/ -/* 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) -{ - gchar *code, *p; - glBarcode *gbc; - gdouble x, y, length, width; - - /* First get code string */ - code = onecode_code (digits); - 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; - } - - g_free (code); - - gbc->width = x + ONECODE_HORIZ_MARGIN; - gbc->height = ONECODE_FULL_HEIGHT + 2 * ONECODE_VERT_MARGIN; - - return gbc; -} - - -/*--------------------------------------------------------------------------*/ -/* PRIVATE. Generate string of symbols, representing barcode. */ -/*--------------------------------------------------------------------------*/ -static gchar * -onecode_code (const gchar *digits) -{ - 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) ) - { - return NULL; - } - - - /*-----------------------------------------------------------*/ - /* Step 1 -- Conversion of Data Fields into Binary Data */ - /*-----------------------------------------------------------*/ - - /* Step 1.a -- Routing Code */ - for ( i = 20; digits[i] != 0; i++ ) - { - int104_mult_uint (&value, 10); - int104_add_uint (&value, digits[i] - '0'); - } - switch ( i-20 ) - { - case 0: - break; - case 5: - int104_add_uint (&value, 1); - break; - case 9: - int104_add_uint (&value, 1); - int104_add_uint (&value, 100000); - break; - case 11: - int104_add_uint (&value, 1); - int104_add_uint (&value, 100000); - int104_add_uint64 (&value, 1000000000); - break; - default: - return NULL; /* Should not happen if length tests passed. */ - break; - } - - /* Step 1.b -- Tracking Code */ - int104_mult_uint (&value, 10); - int104_add_uint (&value, digits[0] - '0'); - int104_mult_uint (&value, 5); - int104_add_uint (&value, digits[1] - '0'); - - for ( i = 2; i < 20; i++ ) - { - int104_mult_uint (&value, 10); - int104_add_uint (&value, digits[i] - '0'); - } - - - /*-----------------------------------------------------------*/ - /* Step 2 -- Generation of 11-Bit CRC on Binary Data */ - /*-----------------------------------------------------------*/ - - crc11 = USPS_MSB_Math_CRC11GenerateFrameCheckSequence( value.byte ); - - - /*-----------------------------------------------------------*/ - /* Step 3 -- Conversion of Binary Data to Codewords */ - /*-----------------------------------------------------------*/ - - codeword[9] = int104_div_uint (&value, 636); - for ( i = 8; i >= 1; i-- ) - { - codeword[i] = int104_div_uint (&value, 1365); - } - codeword[0] = int104_div_uint (&value, 659); - - - /*-----------------------------------------------------------*/ - /* Step 4 -- Inserting Additional Information into Codewords */ - /*-----------------------------------------------------------*/ - - codeword[9] *= 2; - codeword[0] += (crc11 & 0x400) ? 659 : 0; - - - /*-----------------------------------------------------------*/ - /* Step 5 -- Conversion from Codewords to Characters */ - /*-----------------------------------------------------------*/ - - for ( i = 0; i < 10; i++ ) - { - character[i] = character_table[ codeword[i] ]; - - if ( crc11 & (1<str); - g_string_free (code, TRUE); - - return ret; -} - - -/*--------------------------------------------------------------------------*/ -/* Validate if string is of proper length & contains only valid characters. */ -/*--------------------------------------------------------------------------*/ -static gboolean -is_string_valid (const gchar *digits) -{ - gchar *p; - gint str_length; - - if (!digits) { - return FALSE; - } - - str_length = strlen (digits); - if ( (str_length != 20) && - (str_length != 25) && - (str_length != 29) && - (str_length != 31) ) - { - return FALSE; - } - - for ( p = (gchar *)digits; *p != 0; p++ ) - { - if (!g_ascii_isdigit (*p)) - { - return FALSE; - } - } - - if (digits[1] > '4') - { - return FALSE; /* Invalid Barcode Identifier. */ - } - - return TRUE; -} - - -/*--------------------------------------------------------------------------*/ -/* Multiply 104 bit integer by unsigned int. */ -/*--------------------------------------------------------------------------*/ -static void -int104_mult_uint (Int104 *x, - guint y) -{ - gint i; - guint64 temp, carry; - - carry = 0; - for ( i = 12; i >= 0; i-- ) - { - temp = x->byte[i] * y + carry; - - x->byte[i] = temp & 0xFF; - carry = temp >> 8; - } -} - - -/*--------------------------------------------------------------------------*/ -/* Add unsigned int to 104 bit integer. */ -/*--------------------------------------------------------------------------*/ -static void -int104_add_uint (Int104 *x, - guint y) -{ - gint i; - guint temp, carry; - - carry = 0; - for ( i = 12; i >= 0; i-- ) - { - temp = x->byte[i] + (y & 0xFF) + carry; - - x->byte[i] = temp & 0xFF; - carry = temp >> 8; - y = y >> 8; - } -} - - -/*--------------------------------------------------------------------------*/ -/* Add unsigned 64 bit integer to 104 bit integer. */ -/*--------------------------------------------------------------------------*/ -static void -int104_add_uint64 (Int104 *x, - guint64 y) -{ - gint i; - guint64 temp, carry; - - carry = 0; - for ( i = 12; i >= 0; i-- ) - { - temp = x->byte[i] + (y & 0xFF) + carry; - - x->byte[i] = temp & 0xFF; - carry = temp >> 8; - y = y >> 8; - } -} - - -/*--------------------------------------------------------------------------*/ -/* Divide 104 bit integer by unsigned int. */ -/*--------------------------------------------------------------------------*/ -static guint -int104_div_uint (Int104 *x, - guint y) -{ - guint carry, tmp, i; - - carry = 0; - for ( i = 0; i < 13; i++ ) - { - tmp = x->byte[i] + (carry<<8); - x->byte[i] = tmp / y; - carry = tmp % y; - } - - return carry; -} - - -/*--------------------------------------------------------------------------*/ -/* Print hex representation of 104 bit integer. (For debugging) */ -/*--------------------------------------------------------------------------*/ -static void -int104_print (Int104 *x) -{ - gint i; - - for ( i = 0; i < 13; i++ ) - { - g_print ("%02x ", x->byte[i] & 0xFF); - } - g_print ("\n"); -} - - -/*************************************************************************** - ** USPS_MSB_Math_CRC11GenerateFrameCheckSequence - ** - ** Inputs: - ** ByteAttayPtr is the address of a 13 byte array holding 102 bytes which - ** are right justified - ie: the leftmost 2 bits of the first byte do not - ** hold data and must be set to zero. - ** - ** Outputs: - ** return unsigned short - 11 bit Frame Check Sequence (right justified) - ** - ** From Appendix C of USPS publication USPS-B-3200E, 07/08/05. - ***************************************************************************/ -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 ) - { - FrameCheckSequence = (FrameCheckSequence << 1) ^ GeneratorPolynomial; - } - else - { - 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 = (FrameCheckSequence << 1) ^ GeneratorPolynomial; - } - else - { - FrameCheckSequence = (FrameCheckSequence << 1); - } - FrameCheckSequence &= 0x7FF; - Data <<= 1; - } - } - - return FrameCheckSequence; -} - - - - -/* - * 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/src/bc-onecode.h deleted file mode 100644 index dec3e3bc..00000000 --- a/src/bc-onecode.h +++ /dev/null @@ -1,48 +0,0 @@ -/* - * bc-onecode.h - * Copyright (C) 2010 Jim Evins . - * - * 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 . - */ - -#ifndef __BC_ONECODE_H__ -#define __BC_ONECODE_H__ - -#include "bc.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); - -G_END_DECLS - -#endif /* __BC_ONECODE_H__ */ - - - -/* - * Local Variables: -- emacs - * mode: C -- emacs - * c-basic-offset: 8 -- emacs - * tab-width: 8 -- emacs - * indent-tabs-mode: nil -- emacs - * End: -- emacs - */ diff --git a/src/bc-postnet.c b/src/bc-postnet.c deleted file mode 100644 index 5ed6b877..00000000 --- a/src/bc-postnet.c +++ /dev/null @@ -1,225 +0,0 @@ -/* - * bc-postnet.c - * Copyright (C) 2001-2009 Jim Evins . - * - * 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 . - */ - -/* - * This module implements the POSTNET barcode specified in the USPS - * publication 25, Mar 2001. - */ - -#include - -#include "bc-postnet.h" - -#include -#include - -#include "debug.h" - - -/*========================================================*/ -/* Private macros and constants. */ -/*========================================================*/ -#define POSTNET_BAR_WIDTH 1.25 -#define POSTNET_FULLBAR_HEIGHT 9.00 -#define POSTNET_HALFBAR_HEIGHT 3.50 -#define POSTNET_BAR_PITCH 3.25 -#define POSTNET_HORIZ_MARGIN 9.00 -#define POSTNET_VERT_MARGIN 3.00 - - -/*===========================================*/ -/* 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_code (const gchar *digits); - -static gboolean is_length_valid (const gchar *digits, - gint n); - - -/****************************************************************************/ -/* Generate list of lines that form the barcode for the given digits. */ -/****************************************************************************/ -glBarcode * -gl_barcode_postnet_new (const gchar *id, - gboolean text_flag, - gboolean checksum_flag, - gdouble w, - gdouble h, - const gchar *digits) -{ - gchar *code, *p; - glBarcode *gbc; - gdouble x, y, length, width; - - /* Validate code length for all subtypes. */ - if ( (g_ascii_strcasecmp (id, "POSTNET") == 0) ) { - if (!is_length_valid (digits, 5) && - !is_length_valid (digits, 9) && - !is_length_valid (digits, 11)) { - return NULL; - } - } - if ( (g_ascii_strcasecmp (id, "POSTNET-5") == 0) ) { - if (!is_length_valid (digits, 5)) { - return NULL; - } - } - if ( (g_ascii_strcasecmp (id, "POSTNET-9") == 0) ) { - if (!is_length_valid (digits, 9)) { - return NULL; - } - } - if ( (g_ascii_strcasecmp (id, "POSTNET-11") == 0) ) { - if (!is_length_valid (digits, 11)) { - return NULL; - } - } - if ( (g_ascii_strcasecmp (id, "CEPNET") == 0) ) { - if (!is_length_valid (digits, 8)) { - return NULL; - } - } - - /* First get code string */ - code = postnet_code (digits); - if (code == NULL) { - return NULL; - } - - gbc = gl_barcode_new (); - - /* Now traverse the code string and create a list of lines */ - x = POSTNET_HORIZ_MARGIN; - for (p = code; *p != 0; p++) { - y = POSTNET_VERT_MARGIN; - if (*p == '0') { - y += POSTNET_FULLBAR_HEIGHT - POSTNET_HALFBAR_HEIGHT; - length = POSTNET_HALFBAR_HEIGHT; - } else { - length = POSTNET_FULLBAR_HEIGHT; - } - width = POSTNET_BAR_WIDTH; - - gl_barcode_add_line (gbc, x, y, length, width); - - x += POSTNET_BAR_PITCH; - } - - g_free (code); - - gbc->width = x + POSTNET_HORIZ_MARGIN; - gbc->height = POSTNET_FULLBAR_HEIGHT + 2 * POSTNET_VERT_MARGIN; - - return gbc; -} - - -/*--------------------------------------------------------------------------*/ -/* PRIVATE. Generate string of symbols, representing barcode. */ -/*--------------------------------------------------------------------------*/ -static gchar * -postnet_code (const gchar *digits) -{ - gchar *p; - gint len; - gint d, sum; - GString *code; - gchar *ret; - - /* Left frame bar */ - code = g_string_new (frame_symbol); - - sum = 0; - for (p = (gchar *)digits, 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); - - ret = g_strdup (code->str); - g_string_free (code, TRUE); - - return ret; -} - - -/*--------------------------------------------------------------------------*/ -/* Validate specific length of string (for subtypes). */ -/*--------------------------------------------------------------------------*/ -static gboolean -is_length_valid (const gchar *digits, - gint n) -{ - gchar *p; - gint i; - - if (!digits) { - return FALSE; - } - - for (p = (gchar *)digits, i=0; *p != 0; p++) { - if (g_ascii_isdigit (*p)) { - i++; - } - } - - return (i == n); -} - - - -/* - * 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-postnet.h deleted file mode 100644 index 0945670d..00000000 --- a/src/bc-postnet.h +++ /dev/null @@ -1,48 +0,0 @@ -/* - * bc-postnet.h - * Copyright (C) 2001-2009 Jim Evins . - * - * 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 . - */ - -#ifndef __BC_POSTNET_H__ -#define __BC_POSTNET_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); - -G_END_DECLS - -#endif /* __BC_POSTNET_H__ */ - - - -/* - * Local Variables: -- emacs - * mode: C -- emacs - * c-basic-offset: 8 -- emacs - * tab-width: 8 -- emacs - * indent-tabs-mode: nil -- emacs - * End: -- emacs - */ diff --git a/src/bc-zint.c b/src/bc-zint.c index d96e5d7f..e68efc81 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 c0a797d6..2355363b 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 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 8b1810d1..6cc93b5c 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); }