1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */
4 * (GLABELS) Label and Business Card Creation program for GNOME
6 * bc_postnet.c: GLabels POSTNET barcode module
8 * Copyright (C) 2001-2003 Jim Evins <evins@snaught.com>.
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
26 * This module implements the POSTNET barcode specified in the USPS
27 * publication 25, Mar 2001.
32 #include "bc-postnet.h"
35 #include <glib/gstring.h>
36 #include <glib/gstrfuncs.h>
37 #include <glib/gmessages.h>
41 /*========================================================*/
42 /* Private macros and constants. */
43 /*========================================================*/
44 #define POSTNET_BAR_WIDTH 1.25
45 #define POSTNET_FULLBAR_HEIGHT 9.00
46 #define POSTNET_HALFBAR_HEIGHT 3.50
47 #define POSTNET_BAR_PITCH 3.25
48 #define POSTNET_HORIZ_MARGIN 9.00
49 #define POSTNET_VERT_MARGIN 3.00
51 /*===========================================*/
53 /*===========================================*/
54 static gchar *symbols[] = {
67 static gchar *frame_symbol = "1";
69 /*===========================================*/
70 /* Local function prototypes */
71 /*===========================================*/
72 static gchar *postnet_code (const gchar *digits);
74 static gboolean is_length_valid (const gchar *digits,
78 /****************************************************************************/
79 /* Generate list of lines that form the barcode for the given digits. */
80 /****************************************************************************/
82 gl_barcode_postnet_new (const gchar *id,
84 gboolean checksum_flag,
94 /* Validate code length for all subtypes. */
95 if ( (g_strcasecmp (id, "POSTNET") == 0) ) {
96 if (!is_length_valid (digits, 5) &&
97 !is_length_valid (digits, 9) &&
98 !is_length_valid (digits, 11)) {
102 if ( (g_strcasecmp (id, "POSTNET-5") == 0) ) {
103 if (!is_length_valid (digits, 5)) {
107 if ( (g_strcasecmp (id, "POSTNET-9") == 0) ) {
108 if (!is_length_valid (digits, 9)) {
112 if ( (g_strcasecmp (id, "POSTNET-11") == 0) ) {
113 if (!is_length_valid (digits, 11)) {
117 if ( (g_strcasecmp (id, "CEPNET") == 0) ) {
118 if (!is_length_valid (digits, 8)) {
123 /* First get code string */
124 code = postnet_code (digits);
129 gbc = g_new0 (glBarcode, 1);
131 /* Now traverse the code string and create a list of lines */
132 x = POSTNET_HORIZ_MARGIN;
133 for (p = code; *p != 0; p++) {
134 line = g_new0 (glBarcodeLine, 1);
136 line->y = POSTNET_VERT_MARGIN;
139 POSTNET_FULLBAR_HEIGHT - POSTNET_HALFBAR_HEIGHT;
140 line->length = POSTNET_HALFBAR_HEIGHT;
142 line->length = POSTNET_FULLBAR_HEIGHT;
144 line->width = POSTNET_BAR_WIDTH;
146 gbc->lines = g_list_append (gbc->lines, line);
148 x += POSTNET_BAR_PITCH;
153 gbc->width = x + POSTNET_HORIZ_MARGIN;
154 gbc->height = POSTNET_FULLBAR_HEIGHT + 2 * POSTNET_VERT_MARGIN;
161 /*--------------------------------------------------------------------------*/
162 /* PRIVATE. Generate string of symbols, representing barcode. */
163 /*--------------------------------------------------------------------------*/
165 postnet_code (const gchar *digits)
174 code = g_string_new (frame_symbol);
177 for (p = (gchar *)digits, len = 0; (*p != 0) && (len < 11); p++) {
178 if (g_ascii_isdigit (*p)) {
179 /* Only translate valid characters (0-9) */
182 code = g_string_append (code, symbols[d]);
187 /* Create correction character */
188 d = (10 - (sum % 10)) % 10;
189 code = g_string_append (code, symbols[d]);
191 /* Right frame bar */
192 code = g_string_append (code, frame_symbol);
194 ret = g_strdup (code->str);
195 g_string_free (code, TRUE);
200 /*--------------------------------------------------------------------------*/
201 /* Validate specific length of string (for subtypes). */
202 /*--------------------------------------------------------------------------*/
204 is_length_valid (const gchar *digits,
214 for (p = (gchar *)digits, i=0; *p != 0; p++) {
215 if (g_ascii_isdigit (*p)) {