Precisely Speaking
July 23, 2014, 01:00:51 am *
Welcome, Guest. Please login or register.

Login with username, password and session length
News: So what's news with you?  Tell us about it in "Getting To Know You"!
 
   Home   Help Calendar Login Register  
Pages: [1]   Go Down
  Print  
Author Topic: Using PCL to generate Code 39 (3 of 9) Barcodes  (Read 10246 times)
Tom Pellitieri
Rock Star
*****
Posts: 190


Tom Pellitieri - Toledo, Ohio


« on: October 29, 2008, 12:25:42 pm »

I was contacted today by someone looking for my old notes on generating barcodes using PCL from UniBasic.  I hope folks here will find this information useful as well.

The Code 39 (aka 3 of 9) Barcode uses 9 bars for each character: five black and four white.  Of these 3 are "wide" bars, while the rest are "narrow" bars (hence, 3 of 9).

This function will convert an alphanumeric string to a PCL string that will generate the barcode.

Code:
      FUNCTION CEI.HP.3OF9(TXT,HIGH,WIDE)
*
* Converts TXT to the PCL5 string to print as a 3 of 9 Barcode
* Input:  TXT  - Original Text
*         HIGH - Height in Dots
*         WIDE - Narrow Bar Width
* Output: STR  - Return String
*
* Define Valid Characters and corresponding 3 Wide Bar Sets
*
      CMAP = "* $%+-./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
      MAP = "257.237.246.468.268.279.127.248.457.149.349.134.459.145.345."
      MAP := "479.147.347.169.369.136.569.156.356.679.167.367.567.189.389"
      MAP := ".138.589.158.358.789.178.378.578.129.239.123.259.125.235"
      CONVERT "." TO @AM IN MAP
      DIM BWIDE(10)
      E = CHAR(27)
*
* STR1 Saves the current Cursor position, STRZ Restores it.
* Force Text to Upper Case and remove asterisks, since they
* are used to denote the start and end of the barcode.
*
      STR1 = E:"&f0S":E:"*p+":WIDE*10:"X"
      STRZ = E:"&f1S"
      STR = ""
      NTXT = OCONV(TXT,"MCU")
      CONVERT "*" TO "" IN NTXT
      NTXT = "*":NTXT:"*"
      IX = LEN(NTXT)
*
* Convert each character to a set of 5 solid rectangles.  The
* character must be in the valid character set.
* BWIDE is the width of each bar, which is tripled for 3 of
* the 9 bars in the code.  Even bars are white, odd are black.
* The 10th bar is the space between characters.
* PCL Commands draw a bar, then move the drawing cursor the
* width of that bar plus the space afterwards.
*
      IF IX > 2 THEN
         FOR I = 1 TO IX
            LOC = INDEX(CMAP,NTXT[I,1],1)
            IF LOC # 0 THEN
               BMAP = MAP<LOC>
               MAT BWIDE = WIDE
               FOR J = 1 TO 3
                  BWIDE(BMAP[J,1]) *= 3
               NEXT J
               FOR J = 1 TO 9 STEP 2
                  STR := E:"*c":BWIDE(J):"a":HIGH:"b0P"
                  STR := E:"*p+":BWIDE(J)+BWIDE(J+1):"X"
               NEXT J
            END
         NEXT I
         STR = STR1:STR:STRZ
      END
      RETURN STR

I have compiled this under the name CEI.HP.3OF9 but that can be changed.  Just make certain you use the cataloged name in the DEFFUN statement in the program that calls this function.

Here is a sample program I use to print the codes needed to set up our scanners.  I also use PC-8 Line Draw characters to outline each item in a chart. 

Code:
* Print Setup Code Barcodes for LS1900 Barcode Reader
*
* CLIST is the command list.  TLIST is the Display Text.
*
      DEFFUN BAR39(TXT,HIGH,WIDE) CALLING "CEI.HP.3OF9"
      CLIST = "D2C8;C015;C050;C107;C208;C300;C401;C51"
      TLIST = "Defaults;IBM Terminal;ASCII Mode;38400 Baud;8 Data Bits"
      TLIST := ";No Parity;1 Stop Bit;XON/XOFF Enabled"
      CONVERT ";" TO @AM IN CLIST
      CONVERT ";" TO @AM IN TLIST
*
* Define Horizontal Lines using Line Draw characters.
* TLINE is the top line
* DLINE has "T" connectors
* FLINE is the footer
* BLINE is a blank line with end characters
*
      HLINE = STR(CHAR(196),78)
      TLINE = CHAR(218):HLINE:CHAR(191)
      DLINE = CHAR(195):HLINE:CHAR(180)
      FLINE = CHAR(192):HLINE:CHAR(217)
      BLINE = CHAR(179):SPACE(78):CHAR(179)
*
* Print text and barcode below in boxes.  Note that we print
* the Line Draw line, then a carriage return, then position
* the Bar Code.  The Bar Code uses the current print line as
* the TOP of the code, so it actually appears in the line
* below the one on which it is written.
*
      PRINTER ON
      PRINT CHAR(27):"(10U":CHAR(27):"(s0p10h12v0s0b3T":
      PRINT "LS1900 Barcode Reader Setup - Scan All Codes in Order"
      PRINT TLINE
      FOR I = 1 TO 8
         BTEXT = "$+$-":CLIST<I>:"EE"
         PRINT CHAR(179):"  ":TLIST<I> "L#76":CHAR(179)
         PRINT BLINE:CHAR(13):SPACE(15):BAR39(BTEXT,91,3)
         PRINT BLINE
         PRINT BLINE
         IF I = 8 THEN PRINT FLINE ELSE PRINT DLINE
      NEXT I
      PRINT CHAR(27):"E"
      PRINTER OFF
      PRINTER CLOSE

Please note that the barcode prints DOWN from the current page location, which is the character baseline.  You effectively need to print the barcode on the line above where you want it to appear.  I also recommend printing the regular text, then a Carriage Return/CHAR(13) before positioning and printing the barcode.

Also, please note that I use AIX, and have my print queues set so they don't automatically wrap long lines.  This is very important, since each character in the barcode becomes about 15 characters of PCL.

--Tom Pellitieri
Logged
precisonline
President/Chief Technologist
Administrator
Rock Star
*****
Posts: 1550



WWW
« Reply #1 on: October 30, 2008, 03:16:55 pm »

Wow, thanks for sharing - I can't wait to give this a try!  This should work on any HP PCL printers, or specific PCL versions only?
Logged

-Kevin
Accidents "happen"; success, however, is planned and executed.
Tom Pellitieri
Rock Star
*****
Posts: 190


Tom Pellitieri - Toledo, Ohio


« Reply #2 on: October 31, 2008, 05:23:39 am »

The code uses the following PCL commands:

  • Horizontal Cursor Positioning:  (esc)*p relative_offset X
  • Save Cursor Position: (esc)&f0S
  • Restore Cursor Position: (esc)&f1S
  • Solid Rectangular Area Fill Graphics: (esc)*c width a height b 0P
.
These are documented under PCL 5, and should work on later versions.  I haven't tried them under PCL 3, so I'd be interested if this works on an older ink-jet.

--Tom
Logged
nmorgan
Professional
***
Posts: 40


Norman Morgan


WWW
« Reply #3 on: October 31, 2008, 08:41:16 am »

Where were you back when I was struggling to find a code 39 soft font to upload to my printers!  <grin>

You don't have any magic solution for MICR fonts, do you?
Logged

My wife says her life is like a fairy tale.
She married a prince and he turned into a toad.
Tom Pellitieri
Rock Star
*****
Posts: 190


Tom Pellitieri - Toledo, Ohio


« Reply #4 on: October 31, 2008, 12:04:28 pm »

Magic???  No...

We licensed our MICR font from Elfring Fonts a loooong time ago.  I seem to recall that I added a PCL command to provide the soft font ID number for subsequent jobs.  The raw data was transferred from Windows to AIX via Binary FTP. 

I use PCPERFORM "lp -d<queue> <filename>" from my UniBasic program to send the font to the printer prior to printing checks.

(I just looked at the package postmark - March 1997 - thanks for reminding me how long I've been at this... Tongue)

--Tom
Logged
nmorgan
Professional
***
Posts: 40


Norman Morgan


WWW
« Reply #5 on: October 31, 2008, 02:57:23 pm »

We bought the same font, only we store it in the printers in flash memory along with the code 39 fonts and the forms overlays (the last stored as PCL macros).  We've been doing that for a long time....at least long before Prelude partnered with Optio.  We begged them for years for forms overlay printing.  When they never came through, we did it in-house.
Logged

My wife says her life is like a fairy tale.
She married a prince and he turned into a toad.
Pages: [1]   Go Up
  Print  
 
Jump to:  

Powered by MySQL Powered by PHP Powered by SMF 1.1.7 | SMF © 2006-2008, Simple Machines LLC Valid XHTML 1.0! Valid CSS!