[comp.lang.postscript] Barcode Source - 3of9 and UPC

jad@dayton.UUCP (J. Deters) (05/02/89)

Does anyone need any line-eater fodder anymore?

This is the 3 of 9 barcode and UPC barcode source I mentioned earlier.
The UPC barcode was created by Pipeline Associates and was posted to
the net about a year ago.  I modified it slightly to print the human-
readable form beside and below the code.  (The type and check digits
are displayed for our application.  You may wish to supress them.)
I wrote the 3 of 9 barcode stuff based upon the UPC stuff.  (The code
is a good example of a user-defined font.)

I'm still looking for Interleaved 2 of 5, EAN, and any other formats
I can get my grubby hands on.  

SPECIAL NOTE:  I forgot to stress the importance of the asterisks in
the 3of9 format.  3 of 9 *MUST HAVE* asterisks at the beginning and end
of the barcode (see the file 3of9 for an example) or your scanner
probably won't recognize it.  Also, if anyone has a public-domain OCR-A
or OCR-B font, it'd look really cool below the barcode.

Mail comments, problems, flames, gold bullion, etc. to
john@jaded.DHDSC.MN.ORG  or  John Deters
							 4423 Slater Road
                             Eagan, MN  55122

--cut here----cut here----cut here----cut here----cut here--
#! /bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of shell archive."
# Contents:  3of9 3of9.pro upc upc.pro
# Wrapped by john@jaded.DHDSC.MN.ORG on Tue May  1 21:34:57 1989
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f '3of9' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'3of9'\"
else
echo shar: Extracting \"'3of9'\" \(527 characters\)
cat >'3of9' <<'END_OF_FILE'
#!/bin/sh
# 3of9 -- print 3of9 code with PostScript
# usage:  3of9 "text to print" | lpr -qps

# Copyright (C) 1988 by J. Deters Consulting
# Permission is granted to use and distribute as long as this copyright
# notice remains intact and it is distributed free of charge.

THREEOF9PRO=./3of9.pro
X=1	# x coordinate of lower right corner (in inches)
Y=1	# x coordinate of lower right corner (in inches)

cat $THREEOF9PRO
echo "/3of9 findfont 50 scalefont setfont
$X 72 mul $Y 72 mul translate
0 0 moveto
(*$**) show
showpage"
END_OF_FILE
if test 527 -ne `wc -c <'3of9'`; then
    echo shar: \"'3of9'\" unpacked with wrong size!
fi
chmod +x '3of9'
# end of '3of9'
fi
if test -f '3of9.pro' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'3of9.pro'\"
else
echo shar: Extracting \"'3of9.pro'\" \(8386 characters\)
cat >'3of9.pro' <<'END_OF_FILE'
%
%  3 of 9 font.  Copyright (C) 1989, John Deters.  All rights reserved.
%  Permission is hereby granted to freely use this software in a non-
%  commercial application, as long as this notice is preserved.
%
/3of9FontDict 55 dict def
/workdict 55 dict def 
% load up drawing procedures
workdict begin
	/sp1 {
		1 setgray
		2 setlinewidth
		1 0 moveto 1 75 lineto stroke
		2 0 translate
	} bind def
	/sp2 {
		1 setgray
		5 setlinewidth
		2.5 0 moveto 2.5 75 lineto stroke
		5 0 translate
	} bind def
	/mk1 {
		0 setgray
		2 setlinewidth
		1 0 moveto 1 75 lineto stroke
		2 0 translate
	} bind def
	/mk2 {
		0 setgray
		5 setlinewidth
		2.5 0 moveto 2.5 75 lineto stroke
		5 0 translate
	} bind def
end

3of9FontDict begin
/FontType 3 def
/FontMatrix [.01 0 0 .01 0 0] def
/FontBBox [0 0 10 100] def
/Encoding 128 array def
/Widths 128 array def

% Put the proc names of each character in the array 'Encoding'
0 1 127 {Encoding exch /.notdef put} for
Encoding (1) 0 get /one put
Encoding (2) 0 get /two put
Encoding (3) 0 get /three put
Encoding (4) 0 get /four put
Encoding (5) 0 get /five put
Encoding (6) 0 get /six put
Encoding (7) 0 get /seven put
Encoding (8) 0 get /eight put
Encoding (9) 0 get /nine put
Encoding (0) 0 get /zero put
Encoding (A) 0 get /leta put
Encoding (B) 0 get /letb put
Encoding (C) 0 get /letc put
Encoding (D) 0 get /letd put
Encoding (E) 0 get /lete put
Encoding (F) 0 get /letf put
Encoding (G) 0 get /letg put
Encoding (H) 0 get /leth put
Encoding (I) 0 get /leti put
Encoding (J) 0 get /letj put
Encoding (K) 0 get /letk put
Encoding (L) 0 get /letl put
Encoding (M) 0 get /letm put
Encoding (N) 0 get /letn put
Encoding (O) 0 get /leto put
Encoding (P) 0 get /letp put
Encoding (Q) 0 get /letq put
Encoding (R) 0 get /letr put
Encoding (S) 0 get /lets put
Encoding (T) 0 get /lett put
Encoding (U) 0 get /letu put
Encoding (V) 0 get /letv put
Encoding (W) 0 get /letw put
Encoding (X) 0 get /letx put
Encoding (Y) 0 get /lety put
Encoding (Z) 0 get /letz put
Encoding (a) 0 get /leta put
Encoding (b) 0 get /letb put
Encoding (c) 0 get /letc put
Encoding (d) 0 get /letd put
Encoding (e) 0 get /lete put
Encoding (f) 0 get /letf put
Encoding (g) 0 get /letg put
Encoding (h) 0 get /leth put
Encoding (i) 0 get /leti put
Encoding (j) 0 get /letj put
Encoding (k) 0 get /letk put
Encoding (l) 0 get /letl put
Encoding (m) 0 get /letm put
Encoding (n) 0 get /letn put
Encoding (o) 0 get /leto put
Encoding (p) 0 get /letp put
Encoding (q) 0 get /letq put
Encoding (r) 0 get /letr put
Encoding (s) 0 get /lets put
Encoding (t) 0 get /lett put
Encoding (u) 0 get /letu put
Encoding (v) 0 get /letv put
Encoding (w) 0 get /letw put
Encoding (x) 0 get /letx put
Encoding (y) 0 get /lety put
Encoding (z) 0 get /letz put
Encoding (-) 0 get /dash put
Encoding (.) 0 get /period put
Encoding ( ) 0 get /space put
Encoding (*) 0 get /star put
Encoding ($) 0 get /dollar put
Encoding (/) 0 get /slash put
Encoding (+) 0 get /plus put
Encoding (%) 0 get /percent put
Encoding (|) 0 get /bar put

Widths (1) 0 get 29 put
Widths (2) 0 get 29 put
Widths (3) 0 get 29 put
Widths (4) 0 get 29 put
Widths (5) 0 get 29 put
Widths (6) 0 get 29 put
Widths (7) 0 get 29 put
Widths (8) 0 get 29 put
Widths (9) 0 get 29 put
Widths (0) 0 get 29 put
Widths (A) 0 get 29 put
Widths (B) 0 get 29 put
Widths (C) 0 get 29 put
Widths (D) 0 get 29 put
Widths (E) 0 get 29 put
Widths (F) 0 get 29 put
Widths (G) 0 get 29 put
Widths (H) 0 get 29 put
Widths (I) 0 get 29 put
Widths (J) 0 get 29 put
Widths (K) 0 get 29 put
Widths (L) 0 get 29 put
Widths (M) 0 get 29 put
Widths (N) 0 get 29 put
Widths (O) 0 get 29 put
Widths (P) 0 get 29 put
Widths (Q) 0 get 29 put
Widths (R) 0 get 29 put
Widths (S) 0 get 29 put
Widths (T) 0 get 29 put
Widths (U) 0 get 29 put
Widths (V) 0 get 29 put
Widths (W) 0 get 29 put
Widths (X) 0 get 29 put
Widths (Y) 0 get 29 put
Widths (Z) 0 get 29 put
Widths (a) 0 get 29 put
Widths (b) 0 get 29 put
Widths (c) 0 get 29 put
Widths (d) 0 get 29 put
Widths (e) 0 get 29 put
Widths (f) 0 get 29 put
Widths (g) 0 get 29 put
Widths (h) 0 get 29 put
Widths (i) 0 get 29 put
Widths (j) 0 get 29 put
Widths (k) 0 get 29 put
Widths (l) 0 get 29 put
Widths (m) 0 get 29 put
Widths (n) 0 get 29 put
Widths (o) 0 get 29 put
Widths (p) 0 get 29 put
Widths (q) 0 get 29 put
Widths (r) 0 get 29 put
Widths (s) 0 get 29 put
Widths (t) 0 get 29 put
Widths (u) 0 get 29 put
Widths (v) 0 get 29 put
Widths (w) 0 get 29 put
Widths (x) 0 get 29 put
Widths (y) 0 get 29 put
Widths (z) 0 get 29 put
Widths (-) 0 get 29 put
Widths (.) 0 get 29 put
Widths ( ) 0 get 29 put
Widths (*) 0 get 29 put
Widths ($) 0 get 29 put
Widths (/) 0 get 29 put
Widths (+) 0 get 29 put
Widths (%) 0 get 29 put
Widths (|) 0 get 4 put

% define each letter in bar code
/CharProcs 55 dict def
CharProcs /.notdef	{} put
CharProcs /one		{ mk2 sp1 mk1 sp2 mk1 sp1 mk1 sp1 mk2 sp1 } put
CharProcs /two		{ mk1 sp1 mk2 sp2 mk1 sp1 mk1 sp1 mk2 sp1 } put
CharProcs /three	{ mk2 sp1 mk2 sp2 mk1 sp1 mk1 sp1 mk1 sp1 } put
CharProcs /four		{ mk1 sp1 mk1 sp2 mk2 sp1 mk1 sp1 mk2 sp1 } put
CharProcs /five		{ mk2 sp1 mk1 sp2 mk2 sp1 mk1 sp1 mk1 sp1 } put
CharProcs /six		{ mk1 sp1 mk2 sp2 mk2 sp1 mk1 sp1 mk1 sp1 } put
CharProcs /seven	{ mk1 sp1 mk1 sp2 mk1 sp1 mk2 sp1 mk2 sp1 } put
CharProcs /eight	{ mk2 sp1 mk1 sp2 mk1 sp1 mk2 sp1 mk1 sp1 } put
CharProcs /nine		{ mk1 sp1 mk2 sp2 mk1 sp1 mk2 sp1 mk1 sp1 } put
CharProcs /zero		{ mk1 sp1 mk1 sp2 mk2 sp1 mk2 sp1 mk1 sp1 } put
CharProcs /leta		{ mk2 sp1 mk1 sp1 mk1 sp2 mk1 sp1 mk2 sp1 } put
CharProcs /letb		{ mk1 sp1 mk2 sp1 mk1 sp2 mk1 sp1 mk2 sp1 } put
CharProcs /letc		{ mk2 sp1 mk2 sp1 mk1 sp2 mk1 sp1 mk1 sp1 } put
CharProcs /letd		{ mk1 sp1 mk1 sp1 mk2 sp2 mk1 sp1 mk2 sp1 } put
CharProcs /lete		{ mk2 sp1 mk1 sp1 mk2 sp2 mk1 sp1 mk1 sp1 } put
CharProcs /letf		{ mk1 sp1 mk2 sp1 mk2 sp2 mk1 sp1 mk1 sp1 } put
CharProcs /letg		{ mk1 sp1 mk1 sp1 mk1 sp2 mk2 sp1 mk2 sp1 } put
CharProcs /leth		{ mk2 sp1 mk1 sp1 mk1 sp2 mk2 sp1 mk1 sp1 } put
CharProcs /leti		{ mk1 sp1 mk2 sp1 mk1 sp2 mk2 sp1 mk1 sp1 } put
CharProcs /letj		{ mk1 sp1 mk1 sp1 mk2 sp2 mk2 sp1 mk1 sp1 } put
CharProcs /letk		{ mk2 sp1 mk1 sp1 mk1 sp1 mk1 sp2 mk2 sp1 } put
CharProcs /letl		{ mk1 sp1 mk2 sp1 mk1 sp1 mk1 sp2 mk2 sp1 } put
CharProcs /letm		{ mk2 sp1 mk2 sp1 mk1 sp1 mk1 sp2 mk1 sp1 } put
CharProcs /letn		{ mk1 sp1 mk1 sp1 mk2 sp1 mk1 sp2 mk2 sp1 } put
CharProcs /leto		{ mk2 sp1 mk1 sp1 mk2 sp1 mk1 sp2 mk1 sp1 } put
CharProcs /letp		{ mk1 sp1 mk2 sp1 mk2 sp1 mk1 sp2 mk1 sp1 } put
CharProcs /letq		{ mk1 sp1 mk1 sp1 mk1 sp1 mk2 sp2 mk2 sp1 } put
CharProcs /letr		{ mk2 sp1 mk1 sp1 mk1 sp1 mk2 sp2 mk1 sp1 } put
CharProcs /lets		{ mk1 sp1 mk2 sp1 mk1 sp1 mk2 sp2 mk1 sp1 } put
CharProcs /lett		{ mk1 sp1 mk1 sp1 mk2 sp1 mk2 sp2 mk1 sp1 } put
CharProcs /letu		{ mk2 sp2 mk1 sp1 mk1 sp1 mk1 sp1 mk2 sp1 } put
CharProcs /letv		{ mk1 sp2 mk2 sp1 mk1 sp1 mk1 sp1 mk2 sp1 } put
CharProcs /letw		{ mk2 sp2 mk2 sp1 mk1 sp1 mk1 sp1 mk1 sp1 } put
CharProcs /letx		{ mk1 sp2 mk1 sp1 mk2 sp1 mk1 sp1 mk2 sp1 } put
CharProcs /lety		{ mk2 sp2 mk1 sp1 mk2 sp1 mk1 sp1 mk1 sp1 } put
CharProcs /letz		{ mk1 sp2 mk2 sp1 mk2 sp1 mk1 sp1 mk1 sp1 } put
CharProcs /dash		{ mk1 sp2 mk1 sp1 mk1 sp1 mk2 sp1 mk2 sp1 } put
CharProcs /period	{ mk2 sp2 mk1 sp1 mk1 sp1 mk2 sp1 mk1 sp1 } put
CharProcs /space	{ mk1 sp2 mk2 sp1 mk1 sp1 mk2 sp1 mk1 sp1 } put
CharProcs /star		{ mk1 sp2 mk1 sp1 mk2 sp1 mk2 sp1 mk1 sp1 } put
CharProcs /dollar	{ mk1 sp2 mk1 sp2 mk1 sp2 mk1 sp1 mk1 sp1 } put
CharProcs /slash	{ mk1 sp2 mk1 sp2 mk1 sp1 mk1 sp2 mk1 sp1 } put
CharProcs /plus		{ mk1 sp2 mk1 sp1 mk1 sp2 mk1 sp2 mk1 sp1 } put
CharProcs /percent	{ mk1 sp1 mk1 sp2 mk1 sp2 mk1 sp2 mk1 sp1 } put
CharProcs /bar		{ mk1 sp1 } put
% PostScript will call BuildChar for each character printed in 3of9.
/BuildChar {
	workdict begin
		/char exch def
		/fontdict exch def
		/charname fontdict /Encoding get char get def
		/charproc fontdict /CharProcs get charname get def
 		charwidth fontdict /Widths get char get def
		charwidth 0 setcharwidth
		gsave
			charproc
 		grestore
	end
} bind def
end
/3of9 3of9FontDict definefont pop
%
% 3of9 is now loaded in the printer and can be used like any other font.
% Don't forget that you must include the stars at both ends of the text.
% Also, you must print out the human readable text beneath the bar code,
% if you wish to conform to MIL-STD-1189A (suppress the asterisks).
%
END_OF_FILE
if test 8386 -ne `wc -c <'3of9.pro'`; then
    echo shar: \"'3of9.pro'\" unpacked with wrong size!
fi
chmod +x '3of9.pro'
# end of '3of9.pro'
fi
if test -f 'upc' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'upc'\"
else
echo shar: Extracting \"'upc'\" \(1363 characters\)
cat >'upc' <<'END_OF_FILE'
#!/bin/sh
# upc -- print upc code with PostScript
# usage:  upc prod code-5 code-5
# prod is the product type (zero for store items)
# code-5 is a five digit code (needs two of these)

# Copyright (C) 1986 by Pipeline Associates, Inc.
# Permission is granted to use and distribute as long as this copyright
# notice remains intact and it is distributed free of charge.

UPCFONT=./upc.pro
X=1	# x coordinate of lower right corner (in inches)
Y=1	# x coordinate of lower right corner (in inches)

# calculate checksum
SUM=`echo "$2
$3
$2
$3" | sed "
	1s/\(.\)\(.\)\(.\)\(.\)\(.\)/a=$1 + \2 + \4/
	2s/\(.\)\(.\)\(.\)\(.\)\(.\)/b=\1 + \3 + \5/
	3s/\(.\)\(.\)\(.\)\(.\)\(.\)/c=\1 + \3 + \5/
	4s/\(.\)\(.\)\(.\)\(.\)\(.\)/s=(a+b)*3+c+\2+\4;(10-(s%10))%10/" | bc`

cat $UPCFONT
echo "gsave
$X 72 mul $Y 72 mul translate
/UPC findfont 50 scalefont setfont
/startbars (| |) def
0 0 moveto
startbars show
($1$2 | | ) show
switch
($3$SUM) show
switch
startbars show
0 setlinecap
12 setlinewidth
/sx1 (| |$1) stringwidth pop def
/sl2 ($2) stringwidth pop def
/sx2 (| |$1$2 | | ) stringwidth pop def
/sl3 ($3) stringwidth pop def
1 setgray
sx1 0 moveto
sl2 0 rlineto
stroke
sx2 0 moveto
sl3 0 rlineto
stroke
0 setgray
/Helvetica findfont 12 scalefont setfont
-15 30 moveto
($1) show
sx1 -4 moveto
($2) show
sx2 -4 moveto
($3) show
100 30 moveto
($SUM) show
grestore
showpage"
END_OF_FILE
if test 1363 -ne `wc -c <'upc'`; then
    echo shar: \"'upc'\" unpacked with wrong size!
fi
chmod +x 'upc'
# end of 'upc'
fi
if test -f 'upc.pro' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'upc.pro'\"
else
echo shar: Extracting \"'upc.pro'\" \(3078 characters\)
cat >'upc.pro' <<'END_OF_FILE'
%%
%%  Universal Product Code font
%%  Copyright (C) 1986 by Pipeline Associates, Inc.
%%  Permission is granted to use and distribute as long as this copyright
%%  notice remains intact and it is distributed free of charge.
%%
/UPCFontDict 8 dict def
/workdict 25 dict def
%% load up drawing procedures
workdict begin
	/gray 0 def
	/d1 {
		1.3 setlinewidth
		1 0 moveto 1 100 lineto stroke
		2 0 translate
	} bind def
	/d2 {
		3.3 setlinewidth
		2 0 moveto 2 100 lineto stroke
		4 0 translate
	} bind def
	/d3 {
		5.3 setlinewidth
		3 0 moveto 3 100 lineto stroke
		6 0 translate
	} bind def
	/d4 {
		7.3 setlinewidth
		4 0 moveto 4 100 lineto stroke
		8 0 translate
	} bind def
	/cline1 {
		1 gray sub setgray
		d1
	} bind def
	/cline2 {
		1 gray sub setgray
		d2
	} bind def
	/cline3 {
		1 gray sub setgray
		d3
	} bind def
	/cline4 {
		1 gray sub setgray
		d4
	} bind def
	/line1 {
		gray setgray
		d1
	} bind def
	/line2 {
		gray setgray
		d2
	} bind def
	/line3 {
		gray setgray
		d3
	} bind def
	/line4 {
		gray setgray
		d4
	} bind def
end
/switch {
	workdict begin /gray 1 gray sub def end
	} def

UPCFontDict begin
/FontType 3 def
/FontMatrix [.01 0 0 .015 0 0] def
/FontBBox [0 0 10 100] def
/Encoding 128 array def
/Widths 128 array def

%% fill the Encoding array with the procs to run for each character
0 1 127 {Encoding exch /.notdef put} for
Encoding (0) 0 get /zero put
Encoding (1) 0 get /one put
Encoding (2) 0 get /two put
Encoding (3) 0 get /three put
Encoding (4) 0 get /four put
Encoding (5) 0 get /five put
Encoding (6) 0 get /six put
Encoding (7) 0 get /seven put
Encoding (8) 0 get /eight put
Encoding (9) 0 get /nine put
Encoding ( ) 0 get /space put
Encoding (|) 0 get /bar put

Widths (0) 0 get 14 put
Widths (1) 0 get 14 put
Widths (2) 0 get 14 put
Widths (3) 0 get 14 put
Widths (4) 0 get 14 put
Widths (5) 0 get 14 put
Widths (6) 0 get 14 put
Widths (7) 0 get 14 put
Widths (8) 0 get 14 put
Widths (9) 0 get 14 put
Widths ( ) 0 get 2 put
Widths (|) 0 get 2 put

%% define the procs
/CharProcs 20 dict def
CharProcs /.notdef {} put
CharProcs /zero {
	cline3 line2 cline1 line1
} put
CharProcs /one {
	cline2 line2 cline2 line1
} put
CharProcs /two {
	cline2 line1 cline2 line2
} put
CharProcs /three {
	cline1 line4 cline1 line1
} put
CharProcs /four {
	cline1 line1 cline3 line2
} put
CharProcs /five {
	cline1 line2 cline3 line1
} put
CharProcs /six {
	cline1 line1 cline1 line4
} put
CharProcs /seven {
	cline1 line3 cline1 line2
} put
CharProcs /eight {
	cline1 line2 cline1 line3
} put
CharProcs /nine {
	cline3 line1 cline1 line2
} put
CharProcs /space {
} put
CharProcs /bar {
	line1
} put
%% BuildChar is called by PS whenever a character is to be imaged out
%% of UPC
/BuildChar {
 workdict begin
  /char exch def
  /fontdict exch def
  /charname fontdict /Encoding get char get def
  /charproc fontdict /CharProcs get charname get def
  /charwidth fontdict /Widths get char get def
  charwidth 0 setcharwidth
  gsave
	charproc
  grestore
 end
} bind def
end
%% register font in postscript font machinery
/UPC UPCFontDict definefont pop
END_OF_FILE
if test 3078 -ne `wc -c <'upc.pro'`; then
    echo shar: \"'upc.pro'\" unpacked with wrong size!
fi
chmod +x 'upc.pro'
# end of 'upc.pro'
fi
echo shar: End of shell archive.
exit 0
---
john@jaded.DHDSC.MN.ORG
"... but if you got a warrant, I guess you're gonna come in." J. Garcia