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 gchar *postnet_encode (const gchar *digits);
72 static gboolean is_length_valid (const gchar *digits,
75 static lglBarcode *postnet_vectorize (const gchar *code);
79 /****************************************************************************/
80 /* Generate list of lines that form the barcode for the given digits. */
81 /****************************************************************************/
83 lgl_barcode_postnet_new (lglBarcodeType type,
85 gboolean checksum_flag,
93 /* Validate code length for all subtypes. */
97 case LGL_BARCODE_TYPE_POSTNET:
98 if (!is_length_valid (data, 5) &&
99 !is_length_valid (data, 9) &&
100 !is_length_valid (data, 11))
106 case LGL_BARCODE_TYPE_POSTNET_5:
107 if (!is_length_valid (data, 5))
113 case LGL_BARCODE_TYPE_POSTNET_9:
114 if (!is_length_valid (data, 9))
120 case LGL_BARCODE_TYPE_POSTNET_11:
121 if (!is_length_valid (data, 11))
127 case LGL_BARCODE_TYPE_CEPNET:
128 if (!is_length_valid (data, 8))
135 g_message ("Invalid barcode type for POSTNET backend.");
140 /* First get code string */
141 code = postnet_encode (data);
147 /* Now vectorize encoded data */
148 bc = postnet_vectorize (code);
156 /*--------------------------------------------------------------------------*/
157 /* PRIVATE. Generate string of symbols, representing barcode. */
158 /*--------------------------------------------------------------------------*/
160 postnet_encode (const gchar *data)
168 code = g_string_new (frame_symbol);
171 for (p = (gchar *)data, len = 0; (*p != 0) && (len < 11); p++)
173 if (g_ascii_isdigit (*p))
175 /* Only translate valid characters (0-9) */
178 code = g_string_append (code, symbols[d]);
183 /* Create correction character */
184 d = (10 - (sum % 10)) % 10;
185 code = g_string_append (code, symbols[d]);
187 /* Right frame bar */
188 code = g_string_append (code, frame_symbol);
190 return g_string_free (code, FALSE);
194 /*--------------------------------------------------------------------------*/
195 /* PRIVATE. Validate specific length of string (for subtypes). */
196 /*--------------------------------------------------------------------------*/
198 is_length_valid (const gchar *data,
209 for (p = (gchar *)data, i=0; *p != 0; p++)
211 if (g_ascii_isdigit (*p))
221 /*--------------------------------------------------------------------------*/
222 /* PRIVATE. Vectorize encoded barcode. */
223 /*--------------------------------------------------------------------------*/
225 postnet_vectorize (const gchar *code)
229 gdouble x, y, length, width;
231 bc = lgl_barcode_new ();
233 /* Now traverse the code string and create a list of lines */
234 x = POSTNET_HORIZ_MARGIN;
235 for (p = (gchar *)code; *p != 0; p++)
237 y = POSTNET_VERT_MARGIN;
241 y += POSTNET_FULLBAR_HEIGHT - POSTNET_HALFBAR_HEIGHT;
242 length = POSTNET_HALFBAR_HEIGHT;
245 length = POSTNET_FULLBAR_HEIGHT;
250 width = POSTNET_BAR_WIDTH;
252 lgl_barcode_add_box (bc, x, y, width, length);
254 x += POSTNET_BAR_PITCH;
257 bc->width = x + POSTNET_HORIZ_MARGIN;
258 bc->height = POSTNET_FULLBAR_HEIGHT + 2 * POSTNET_VERT_MARGIN;
266 * Local Variables: -- emacs
268 * c-basic-offset: 8 -- emacs
269 * tab-width: 8 -- emacs
270 * indent-tabs-mode: nil -- emacs