[comp.lang.postscript] UPC-A barcode generator

phys59@jetson.uh.edu (03/26/91)

%WARNING: EXTREMELY LARGE WASTE OF BANDWIDTH AHEAD
%  For anyone who has a need for it, here's a handy little PostScript UPC
%  generator.

% --------- CUT HERE --------- (or don't - it'll run anyway!)

%The following code is used to generate a UPC-A barcode.
%
%calling sequence:
%    string *Barcode* --
%where string is a 10-digit string of numerics.
%
%Example:
%    (0123456789) Barcode
%
%Output will be in the form of a UPC barcode bounded by the square (0,0)-(1,1)
%Scale and position as necessary before calling.
%
%This code is freely redistributable and is copyright 1991 Ronald L. Parker.
%Universal Product Code, UPC, and the barcode itself may be someone's
%trademarks or property.  If this is the case, I assume no responsibility for
%any damages, in any form, that the use of this code may cause.  Whoever DOES
%own the UPC code - don't come looking for me, I have no money anyway.
 
/bar % width color bar --
       % width is in 'modules' 1-4
       % color: 0=black, 1=white, just like setgray
{
/BarColor exch def
/BarWidth exch def

/Tempwidth BarWidth 95 div def
0 .1 moveto 0 1 lineto Tempwidth 1 lineto Tempwidth .1 lineto closepath
BarColor setgray fill
Tempwidth 0 translate
} def

/dochar % string dochar -- 
        % string is one character, must be supported.
{
/ToOutput exch def

ToOutput 66 eq {1 Dark bar 1 Light bar 1 Dark bar} if
ToOutput 69 eq {1 Light bar 1 Dark bar 1 Light bar} if
ToOutput 77 eq {1 Light bar 1 Dark bar 1 Light bar 1 Dark bar 1 Light bar
                 /Dark 1 def /Light 0 def} if
ToOutput 48 eq {3 Light bar 2 Dark bar 1 Light bar 1 Dark bar} if
ToOutput 49 eq {2 Light bar 2 Dark bar 2 Light bar 1 Dark bar} if
ToOutput 50 eq {2 Light bar 1 Dark bar 2 Light bar 2 Dark bar} if
ToOutput 51 eq {1 Light bar 4 Dark bar 1 Light bar 1 Dark bar} if
ToOutput 52 eq {1 Light bar 1 Dark bar 3 Light bar 2 Dark bar} if
ToOutput 53 eq {1 Light bar 2 Dark bar 3 Light bar 1 Dark bar} if
ToOutput 54 eq {1 Light bar 1 Dark bar 1 Light bar 4 Dark bar} if
ToOutput 55 eq {1 Light bar 3 Dark bar 1 Light bar 2 Dark bar} if
ToOutput 56 eq {1 Light bar 2 Dark bar 1 Light bar 3 Dark bar} if
ToOutput 57 eq {3 Light bar 1 Dark bar 1 Light bar 2 Dark bar} if
} def

/Barcode % string code --
{
gsave
/BarString exch def
/NewString 15 string def
/Dark 0 def
/Light 1 def
NewString 2 BarString 0 5 getinterval putinterval
NewString 8 BarString 5 5 getinterval putinterval
NewString 0 (B0) putinterval
NewString 7 (M) putinterval
NewString 14 (E) putinterval
/CheckSum 0 def
0 1 9 {dup BarString exch 1 getinterval cvi exch 2 mod 2 mul 1 add mul
       CheckSum add /CheckSum exch def} for
CheckSum 10 mod 10 exch sub /CheckSum exch def
NewString 13 CheckSum cvi 1 string cvs putinterval
NewString {dochar} forall
1 setgray
-1 0 translate 10 95 div .1 moveto 45 95 div .1 lineto 45 95 div .2 lineto
               10 95 div .2 lineto closepath fill
               50 95 div .1 moveto 85 95 div .1 lineto 85 95 div .2 lineto
               50 95 div .2 lineto closepath fill
0 setgray
BarFont findfont [7 95 div 0 0 .2 0 0] makefont setfont
0 1 4 {dup 7 mul 10 add 95 div 0 moveto BarString exch 1 getinterval show} for
5 1 9 {dup 7 mul 15 add 95 div 0 moveto BarString exch 1 getinterval show} for
grestore
} def

% This is the preferred font for UPC barcodes:
%/BarFont /OCR-B def

% This is what I use as I don't have OCR-B or any standard Adobe fonts.
% You may insert your own favorite font here.
/BarFont /SansSerif def