2 * lgl-barcode-postnet.c
3 * Copyright (C) 2001-2010 Jim Evins <evins@snaught.com>.
5 * This file is part of libglbarcode.
7 * libglbarcode is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU Lesser General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
12 * libglbarcode is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public License
18 * along with libglbarcode. If not, see <http://www.gnu.org/licenses/>.
22 * This module implements the POSTNET barcode specified in the USPS
23 * publication 25, Mar 2001.
28 #include "lgl-barcode-postnet.h"
34 /*========================================================*/
35 /* Private macros and constants. */
36 /*========================================================*/
38 #define PTS_PER_INCH 72.0
40 #define POSTNET_BAR_WIDTH ( 0.02 * PTS_PER_INCH )
41 #define POSTNET_FULLBAR_HEIGHT ( 0.125 * PTS_PER_INCH )
42 #define POSTNET_HALFBAR_HEIGHT ( 0.05 * PTS_PER_INCH )
43 #define POSTNET_BAR_PITCH ( 0.04545 * PTS_PER_INCH )
44 #define POSTNET_HORIZ_MARGIN ( 0.125 * PTS_PER_INCH )
45 #define POSTNET_VERT_MARGIN ( 0.04 * PTS_PER_INCH )
48 /*===========================================*/
50 /*===========================================*/
51 static gchar *symbols[] = {
64 static gchar *frame_symbol = "1";
67 /*===========================================*/
68 /* Local function prototypes */
69 /*===========================================*/
70 static gint postnet_validate_data (const gchar *data);
72 static gchar *postnet_encode (const gchar *digits);
74 static lglBarcode *postnet_vectorize (const gchar *code);
78 /****************************************************************************/
79 /* Generate new Postnet barcode structure from data. */
80 /****************************************************************************/
82 lgl_barcode_postnet_new (lglBarcodeType type,
84 gboolean checksum_flag,
93 /* Validate data and length for all subtypes. */
94 n_digits = postnet_validate_data (data);
98 case LGL_BARCODE_TYPE_POSTNET:
99 if ( (n_digits != 5) &&
107 case LGL_BARCODE_TYPE_POSTNET_5:
114 case LGL_BARCODE_TYPE_POSTNET_9:
121 case LGL_BARCODE_TYPE_POSTNET_11:
122 if ( n_digits != 11 )
128 case LGL_BARCODE_TYPE_CEPNET:
136 g_message ("Invalid barcode type for POSTNET backend.");
141 /* First get code string */
142 code = postnet_encode (data);
148 /* Now vectorize encoded data */
149 bc = postnet_vectorize (code);
157 /*--------------------------------------------------------------------------*/
158 /* PRIVATE. Validate data, returning number of digits if valid. */
159 /*--------------------------------------------------------------------------*/
161 postnet_validate_data (const gchar *data)
171 for ( p = (gchar *)data, i=0; *p != 0; p++ )
173 if (g_ascii_isdigit (*p))
177 else if ( (*p != '-') && (*p != ' ') )
179 /* Only allow digits, dashes, and spaces. */
188 /*--------------------------------------------------------------------------*/
189 /* PRIVATE. Generate string of symbols, representing barcode. */
190 /*--------------------------------------------------------------------------*/
192 postnet_encode (const gchar *data)
200 code = g_string_new (frame_symbol);
203 for ( p = (gchar *)data, len = 0; (*p != 0) && (len < 11); p++ )
205 if (g_ascii_isdigit (*p))
207 /* Only translate the digits (0-9) */
210 code = g_string_append (code, symbols[d]);
215 /* Create correction character */
216 d = (10 - (sum % 10)) % 10;
217 code = g_string_append (code, symbols[d]);
219 /* Right frame bar */
220 code = g_string_append (code, frame_symbol);
222 return g_string_free (code, FALSE);
226 /*--------------------------------------------------------------------------*/
227 /* PRIVATE. Vectorize encoded barcode. */
228 /*--------------------------------------------------------------------------*/
230 postnet_vectorize (const gchar *code)
234 gdouble x, y, length, width;
236 bc = lgl_barcode_new ();
238 /* Now traverse the code string and create a list of lines */
239 x = POSTNET_HORIZ_MARGIN;
240 for ( p = (gchar *)code; *p != 0; p++ )
242 y = POSTNET_VERT_MARGIN;
246 y += POSTNET_FULLBAR_HEIGHT - POSTNET_HALFBAR_HEIGHT;
247 length = POSTNET_HALFBAR_HEIGHT;
250 length = POSTNET_FULLBAR_HEIGHT;
255 width = POSTNET_BAR_WIDTH;
257 lgl_barcode_add_box (bc, x, y, width, length);
259 x += POSTNET_BAR_PITCH;
262 bc->width = x + POSTNET_HORIZ_MARGIN;
263 bc->height = POSTNET_FULLBAR_HEIGHT + 2 * POSTNET_VERT_MARGIN;
271 * Local Variables: -- emacs
273 * c-basic-offset: 8 -- emacs
274 * tab-width: 8 -- emacs
275 * indent-tabs-mode: nil -- emacs