[glabels/vala] Added native support for UPC-A.



commit 40fb4f4176ca92b83a996b794a0d07689b3b7a8f
Author: Jim Evins <evins snaught com>
Date:   Thu Sep 13 00:34:56 2012 -0400

    Added native support for UPC-A.
    
    This is a proof-of-concept for the extensibility of libglbarcode.  Some
    minor cleanup too.

 glabels/Makefile.am               |    5 +-
 glabels/barcode_backends.vala     |    3 +
 libglbarcode/Makefile.am          |    1 +
 libglbarcode/barcode_code39.vala  |    2 +-
 libglbarcode/barcode_postnet.vala |   18 ++--
 libglbarcode/barcode_upc.vala     |  243 +++++++++++++++++++++++++++++++++++++
 libglbarcode/cairo_renderer.vala  |    2 +-
 libglbarcode/demo/glbarcode.vala  |    2 +-
 libglbarcode/factory.vala         |    1 +
 9 files changed, 264 insertions(+), 13 deletions(-)
---
diff --git a/glabels/Makefile.am b/glabels/Makefile.am
index 0b37d6d..64bff76 100644
--- a/glabels/Makefile.am
+++ b/glabels/Makefile.am
@@ -119,7 +119,10 @@ DISTCLEANFILES = \
 	$(NULL)
 
 
-$(bin_PROGRAMS): libglabels
+$(bin_PROGRAMS): libglabels libglbarcode
 
 libglabels:
 	cd ../libglabels; $(MAKE)
+
+libglbarcode:
+	cd ../libglbarcode; $(MAKE)
diff --git a/glabels/barcode_backends.vala b/glabels/barcode_backends.vala
index 598044e..72a4cb7 100644
--- a/glabels/barcode_backends.vala
+++ b/glabels/barcode_backends.vala
@@ -64,6 +64,9 @@ namespace glabels
 			register( "Code39Ext", _("Code 39 Extended"),
 			          true, true, true, true, "1234567890", true, 10 );
 
+			register( "UPC-A", _("UPC - A"),
+			          true, false, true, false, "12345678901", false, 11 );
+
 #if HAVE_LIBBARCODE
 
 			register( "gnu-barcode:EAN", _("GNU-Barcode : EAN (any)"),
diff --git a/libglbarcode/Makefile.am b/libglbarcode/Makefile.am
index a666c60..13e7362 100644
--- a/libglbarcode/Makefile.am
+++ b/libglbarcode/Makefile.am
@@ -9,6 +9,7 @@ libglbarcode_4_0_la_SOURCES = \
 	barcode_code39_extended.vala \
 	barcode_onecode.vala \
 	barcode_postnet.vala \
+	barcode_upc.vala \
 	shape.vala \
 	renderer.vala \
 	cairo_renderer.vala \
diff --git a/libglbarcode/barcode_code39.vala b/libglbarcode/barcode_code39.vala
index 03d87ef..9b027c2 100644
--- a/libglbarcode/barcode_code39.vala
+++ b/libglbarcode/barcode_code39.vala
@@ -181,7 +181,7 @@ namespace glbarcode
 			/* determine horizontal quiet zone */
 			double x_quiet = double.max( (10 * scale * MIN_X), MIN_QUIET );
 
-			/* Now traverse the code string and each bar */
+			/* Now traverse the code string and draw each bar */
 			double x1 = x_quiet;
 			for ( int i=0; i < coded_data.length; i++ )
 			{
diff --git a/libglbarcode/barcode_postnet.vala b/libglbarcode/barcode_postnet.vala
index 6891fae..9ce5bb8 100644
--- a/libglbarcode/barcode_postnet.vala
+++ b/libglbarcode/barcode_postnet.vala
@@ -101,14 +101,14 @@ namespace glbarcode
 			for ( int i = 0; i < data.length; i++ )
 			{
 				if ( data[i].isdigit() )
-                {
-                        n_digits++;
-                }
-                else if ( (data[i] != '-') && (data[i] != ' ') )
-                {
-                        /* Only allow digits, dashes, and spaces. */
-                        return false;
-                }
+				{
+					n_digits++;
+				}
+				else if ( (data[i] != '-') && (data[i] != ' ') )
+				{
+					/* Only allow digits, dashes, and spaces. */
+					return false;
+				}
 			}
 
 			return validate_digits( n_digits );
@@ -132,7 +132,7 @@ namespace glbarcode
 					int d = data[i] - '0';
 					code.append( symbols[d] );
 					sum += d;
-                }
+				}
 			}
 
 			/* Create mandatory correction character */
diff --git a/libglbarcode/barcode_upc.vala b/libglbarcode/barcode_upc.vala
new file mode 100644
index 0000000..30e5507
--- /dev/null
+++ b/libglbarcode/barcode_upc.vala
@@ -0,0 +1,243 @@
+/*  barcode_upc.vala
+ *
+ *  Copyright (C) 2012  Jim Evins <evins snaught com>
+ *
+ *  This file is part of libglbarcode.
+ *
+ *  libglabels is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU Lesser General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  libglabels 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 Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public License
+ *  along with libglabels.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+using GLib;
+using glbarcode.Constants;
+
+namespace glbarcode
+{
+
+	public class BarcodeUPCA : Barcode
+	{
+
+		private const double MODULE0 = ( 0.01 *  PTS_PER_INCH );
+		private const int    QUIET_MODULES   = 9;
+
+		private const double INK_BLEED   = ( 0.00325 * PTS_PER_INCH );
+
+
+		private const string[] symbols = {
+			/* left:  sBsB */
+			/* right: BsBs */
+			/* 0 */  "3211",
+			/* 1 */  "2221",
+			/* 2 */  "2122",
+			/* 3 */  "1411",
+			/* 4 */  "1132",
+			/* 5 */  "1231",
+			/* 6 */  "1114",
+			/* 7 */  "1312",
+			/* 8 */  "1213",
+			/* 9 */  "3112"
+		};
+
+		private const string s_symbol = "111";   /* BsB */
+		private const string e_symbol = "111";   /* BsB */
+		private const string m_symbol = "11111"; /* sBsBs */
+
+
+		private string check_digit;
+
+
+		protected override bool validate( string data )
+		{
+			int n_digits = 0;
+
+			for ( int i = 0; i < data.length; i++ )
+			{
+				if ( data[i].isdigit() )
+				{
+					n_digits++;
+				}
+				else if ( data[i] != ' ')
+				{
+					/* Only allow digits and spaces. */
+					return false;
+				}
+			}
+
+			if ( n_digits != 11 )
+			{
+				return false;
+			}
+
+			return true;
+		}
+
+
+		protected override string preprocess( string data )
+		{
+			StringBuilder stripped_data = new StringBuilder();
+
+			for ( int i = 0; i < data.length; i++ )
+			{
+				if ( data[i].isdigit() )
+				{
+					stripped_data.append_c( data[i] );
+				}
+			}
+
+			return stripped_data.str;
+		}
+
+
+		protected override string encode( string canon_data, bool checksum_flag )
+		{
+			int sum_odd  = 0;
+			int sum_even = 0;
+
+			StringBuilder code = new StringBuilder();
+
+			/* Left frame symbol */
+			code.append( s_symbol );
+
+			/* Left 6 digits */
+			for ( int i=0; i < 6; i++ )
+			{
+				int c_value = canon_data[i].digit_value();
+				code.append( symbols[c_value] );
+
+				if ( (i & 1) == 0 )
+				{
+					sum_odd += c_value;
+				}
+				else
+				{
+					sum_even += c_value;
+				}
+			}
+
+			/* Middle frame symbol */
+			code.append( m_symbol );
+
+			/* Right 5 digits */
+			for ( int i=6; i < 11; i++ )
+			{
+				int c_value = canon_data[i].digit_value();
+				code.append( symbols[c_value] );
+
+				if ( (i & 1) == 0 )
+				{
+					sum_odd += c_value;
+				}
+				else
+				{
+					sum_even += c_value;
+				}
+			}
+
+			/* Check digit */
+			int check = (3*sum_odd + sum_even) % 10;
+			if ( check != 0 )
+			{
+				check = 10 - check;
+			}
+			code.append( symbols[check] );
+			check_digit = check.to_string(); /* Save for display. */
+
+
+			/* Right frame symbol */
+			code.append( e_symbol );
+
+			return code.str;
+		}
+
+
+		protected override void vectorize( string coded_data,
+		                                   bool text_flag, bool checksum_flag,
+		                                   double w, double h,
+		                                   string data, string text )
+		{
+			/* determine width and establish horizontal scale */
+			int n_modules = 7*(data.length+1) + 11;
+
+			double scale;
+			if ( w == 0 )
+			{
+				scale = 1.0;
+			}
+			else
+			{
+				scale = w / ((n_modules + 2*QUIET_MODULES) * MODULE0);
+
+				if ( scale < 1.0 )
+				{
+					scale = 1.0;
+				}
+			}
+			double width = (n_modules + 2*QUIET_MODULES) * scale * MODULE0;
+
+			/* determine text parameters */
+			double h_text_area = 14 * scale * MODULE0;
+			double text_size1 = 10 * scale * MODULE0;
+			double text_size2 = 0.75*text_size1;
+			double text_c1 = (QUIET_MODULES + 5 + n_modules/4) * scale * MODULE0;
+			double text_c2 = (QUIET_MODULES - 4 + 3*n_modules/4) * scale * MODULE0;
+
+			/* determine bar height */
+			double h_bar1 = double.max( (h - h_text_area), width/2 );
+			double h_bar2 = h_bar1 + h_text_area/2;
+
+			/* determine horizontal quiet zone */
+			double x_quiet = QUIET_MODULES * scale * MODULE0;
+
+			/* now traverse the code string and draw each bar */
+			double x1 = x_quiet;
+			for ( int i=0; i < coded_data.length; i+=2 )
+			{
+				double h_bar;
+
+				if ( ( (i > 7) && (i < (coded_data.length/2-1)) ) ||
+				     ( (i > (coded_data.length/2+1)) && (i < (coded_data.length-7)) ) )
+				{
+					h_bar = h_bar1;
+				}
+				else
+				{
+					h_bar = h_bar2;
+				}
+
+				/* Bar */
+				int bar_w = coded_data[i].digit_value();
+
+				add_box( x1, 0.0, (bar_w*scale*MODULE0 - INK_BLEED), h_bar );
+				x1 += bar_w * scale * MODULE0;
+
+				/* Space */
+				int space_w = coded_data[i+1].digit_value();
+
+				x1 += space_w * scale * MODULE0;
+			}
+
+			/* draw text */
+			add_string( x_quiet/2,       h_bar2 - text_size2/2, text_size2, text[0:1] );
+			add_string( text_c1,         h_bar2 - text_size1/2, text_size1, text[1:6] );
+			add_string( text_c2,         h_bar2 - text_size1/2, text_size1, text[6:11] );
+			add_string( width-x_quiet/2, h_bar2 - text_size2/2, text_size2, check_digit );
+
+			this.w = width;
+			this.h = h_bar1 + h_text_area;
+		}
+
+
+	}
+
+}
diff --git a/libglbarcode/cairo_renderer.vala b/libglbarcode/cairo_renderer.vala
index b234b53..2fe14bc 100644
--- a/libglbarcode/cairo_renderer.vala
+++ b/libglbarcode/cairo_renderer.vala
@@ -28,7 +28,7 @@ namespace glbarcode
 	{
 
 		private const double FONT_SCALE  = 72.0/96;
-		private const string FONT_FAMILY = "Sans";
+		private const string FONT_FAMILY = "Monospace";
 
 
 		private Cairo.Context cr;
diff --git a/libglbarcode/demo/glbarcode.vala b/libglbarcode/demo/glbarcode.vala
index 0928bf7..1cecc7c 100644
--- a/libglbarcode/demo/glbarcode.vala
+++ b/libglbarcode/demo/glbarcode.vala
@@ -59,7 +59,7 @@ namespace glbarcode
 			  "Barcode data",
 			  "DATA"
 			},
-			{ "resolution", 'r', 0, OptionArg.STRING, ref ppi,
+			{ "resolution", 'r', 0, OptionArg.DOUBLE, ref ppi,
 			  "Resolution (Pixels per Inch)",
 			  "PPI"
 			},
diff --git a/libglbarcode/factory.vala b/libglbarcode/factory.vala
index 1a6e0e5..09950bc 100644
--- a/libglbarcode/factory.vala
+++ b/libglbarcode/factory.vala
@@ -64,6 +64,7 @@ namespace glbarcode
 			register_type( "POSTNET-9",       typeof(BarcodePostnet9) );
 			register_type( "POSTNET-11",      typeof(BarcodePostnet11) );
 			register_type( "CEPNET",          typeof(BarcodeCepnet) );
+			register_type( "UPC-A",           typeof(BarcodeUPCA) );
 
 			initialized = true;
 		}



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]