3 * Copyright (C) 2001-2009 Jim Evins <evins@snaught.com>.
5 * This file is part of gLabels.
7 * gLabels is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU 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 * gLabels 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 General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with gLabels. 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 "bc-postnet.h"
36 /*========================================================*/
37 /* Private macros and constants. */
38 /*========================================================*/
39 #define POSTNET_BAR_WIDTH 1.25
40 #define POSTNET_FULLBAR_HEIGHT 9.00
41 #define POSTNET_HALFBAR_HEIGHT 3.50
42 #define POSTNET_BAR_PITCH 3.25
43 #define POSTNET_HORIZ_MARGIN 9.00
44 #define POSTNET_VERT_MARGIN 3.00
47 /*===========================================*/
49 /*===========================================*/
50 static gchar *symbols[] = {
63 static gchar *frame_symbol = "1";
66 /*===========================================*/
67 /* Local function prototypes */
68 /*===========================================*/
69 static gchar *postnet_code (const gchar *digits);
71 static gboolean is_length_valid (const gchar *digits,
75 /****************************************************************************/
76 /* Generate list of lines that form the barcode for the given digits. */
77 /****************************************************************************/
79 gl_barcode_postnet_new (const gchar *id,
81 gboolean checksum_flag,
88 gdouble x, y, length, width;
90 /* Validate code length for all subtypes. */
91 if ( (g_ascii_strcasecmp (id, "POSTNET") == 0) ) {
92 if (!is_length_valid (digits, 5) &&
93 !is_length_valid (digits, 9) &&
94 !is_length_valid (digits, 11)) {
98 if ( (g_ascii_strcasecmp (id, "POSTNET-5") == 0) ) {
99 if (!is_length_valid (digits, 5)) {
103 if ( (g_ascii_strcasecmp (id, "POSTNET-9") == 0) ) {
104 if (!is_length_valid (digits, 9)) {
108 if ( (g_ascii_strcasecmp (id, "POSTNET-11") == 0) ) {
109 if (!is_length_valid (digits, 11)) {
113 if ( (g_ascii_strcasecmp (id, "CEPNET") == 0) ) {
114 if (!is_length_valid (digits, 8)) {
119 /* First get code string */
120 code = postnet_code (digits);
125 gbc = gl_barcode_new ();
127 /* Now traverse the code string and create a list of lines */
128 x = POSTNET_HORIZ_MARGIN;
129 for (p = code; *p != 0; p++) {
130 y = POSTNET_VERT_MARGIN;
132 y += POSTNET_FULLBAR_HEIGHT - POSTNET_HALFBAR_HEIGHT;
133 length = POSTNET_HALFBAR_HEIGHT;
135 length = POSTNET_FULLBAR_HEIGHT;
137 width = POSTNET_BAR_WIDTH;
139 gl_barcode_add_line (gbc, x, y, length, width);
141 x += POSTNET_BAR_PITCH;
146 gbc->width = x + POSTNET_HORIZ_MARGIN;
147 gbc->height = POSTNET_FULLBAR_HEIGHT + 2 * POSTNET_VERT_MARGIN;
153 /*--------------------------------------------------------------------------*/
154 /* PRIVATE. Generate string of symbols, representing barcode. */
155 /*--------------------------------------------------------------------------*/
157 postnet_code (const gchar *digits)
166 code = g_string_new (frame_symbol);
169 for (p = (gchar *)digits, len = 0; (*p != 0) && (len < 11); p++) {
170 if (g_ascii_isdigit (*p)) {
171 /* Only translate valid characters (0-9) */
174 code = g_string_append (code, symbols[d]);
179 /* Create correction character */
180 d = (10 - (sum % 10)) % 10;
181 code = g_string_append (code, symbols[d]);
183 /* Right frame bar */
184 code = g_string_append (code, frame_symbol);
186 ret = g_strdup (code->str);
187 g_string_free (code, TRUE);
193 /*--------------------------------------------------------------------------*/
194 /* Validate specific length of string (for subtypes). */
195 /*--------------------------------------------------------------------------*/
197 is_length_valid (const gchar *digits,
207 for (p = (gchar *)digits, i=0; *p != 0; p++) {
208 if (g_ascii_isdigit (*p)) {
219 * Local Variables: -- emacs
221 * c-basic-offset: 8 -- emacs
222 * tab-width: 8 -- emacs
223 * indent-tabs-mode: nil -- emacs