PC-based applications make Hewlett-Packard LaserJet printers whirl, jig, and print some downright fancy documents. On the iSeries and AS/400, IPDS-defined printers can do sophisticated printing, too. But what about SNA Character Stream-type printers, and HP LaserJet printers, in particular? SNA Character Stream (SCS) allows for basic formatting, but face it, this is really talking about plain vanilla text reports. There are thousands (or more) of HP LaserJet printers connected to iSeries 400 computers by IP connections that are capable of some extraordinary font printing, but the SCS interface doesn’t allow the developer to easily change fonts on a single page. Or does it?
What if we could mix fonts—larger, smaller, and bold, for example—on the same page? That could really open up the possibilities. Perhaps your biggest customer will still be the text report, but it sure would be nice to be able have the tools to print fancy documents every now and again.
To Print the Impossible
But aren’t I talking about an SCS-defined printer here? You can’t dynamically change the fonts within the print file for a SCS device. Often to easily connect a LAN HP LaserJet printer to the AS/400, you use the CRTOUTQ command and specify the printer’s IP address. This sets up an implicit SCS device, and print files sent to the printer must abide by the limitations of SCS. Or do they?
The secret is knowing how to build a command that tells the printer to begin printing a new font and then knowing how to pass this command to the printer. Several methods can be used to accomplish this (see “Use PC Laser Printer Fonts in Your RPG Output” by Ann Willyard in the February 1995 issue of MC), and this article presents one technique. Actually, after going through the various pieces involved, it’s not too daunting a task, and the rewards are simply spectacular. Oh, by the way, it can be done with an IP- connected HP LaserJet printer, even though it’s defined as SCS.
Speaking the Language
The printer’s native language is PCL. This is a series of escape sequences followed by parameters that tell a printer things like how to print, where on the page to print, what the
print looks like, how many times to print, and so on. Most of the time, a developer only uses PCL when the host computer’s interface doesn’t allow a particular function, or when it’s just plain easier to send a PCL command rather than fumble through the host interface.
The HP LaserJet printer likes to receive these commands in hexadecimal format, so before you send the PCL commands to the printer, a translation will need to be made. Normally, OS/400 will translate a print file into the necessary PCL commands. You still want this to happen, but you’re going to need to help the operating system a bit when a fancy font is needed.
This article will only deal with the PCL command to change fonts. There are so many commands in PCL that one article wouldn’t cover them all. Thankfully, OS/400 will continue to translate most of the print file for you, and you only need to concentrate on font changes. The font command consists of two parts: a symbol set and the font attributes. The symbol set defines the allowable characters to print, and the font attributes tell the printer how to print the allowable characters. Together they form the command that will cause a font change on the printer.
The Hex Connection!
When you send a PCL command to the printer, you must code it in hexadecimal format. That is, every character that will be translated must be represented by a pair of hexadecimal digits. Figure 1 (page 46) contains a chart of all of the characters that will be converted into hex pairs for this article.
To convert a character, symbol, or control into a hex pair, first find the character in the table and then find out which row and column it’s in. Finish by writing the row as the first character and the column as the second character. For example, the escape character, ESC (and written below as
Using the chart in Figure 1 as your “secret agent decoder ring” will make translating the PCL commands into hexadecimal kind of like going on a spy mission. But instead of secret codes, you’ll be translating PCL.
The PCL Command
As I mentioned, the command to make font changes has two parts: the symbol set and the font attributes. Say you wanted to print a string of text at 36 points (each point is 1/72 of an inch in height) using the font CG Times.
In the HP LaserJet’s user’s manual, the PCL command for printing CG Times is as follows:
The ** is the point size. The two parts of the command are as follows:
symbol/character
set (IBM PC-8)
in 36 point
Putting both parts of the PCL command together gives you the whole picture:
Using the translation table in Figure 1 and taking it one character at a time, the hex pair representation of the PCL command becomes as follows:
( 28
1 31
0 30
U 55
The complete hex pair representation of
1B283130551B2873317033367630733362
3431303154
Now, take a breath. OS/400 will take care of translating this long string down to the machine level that the printer will actually use. There are several resident fonts on the HP LaserJet printer, so check the printer’s user’s manual for more fonts and the corresponding PCL command to make the font change.
DDS Smoke and Mirrors
Within the DDS of the print file, there are two important field-level keywords that allow you to insert your own PCL commands right smack in the middle of the PCL that OS/400 is generating: TRNSPY and CVTDTA. A data field will contain a text string of the hex pairs like the one above, and these two keywords working together will cause the operating system to change the text into something the printer can understand. The PCL command itself is not printed out on the page, but it does cause the printer to change fonts.
Figure 2 shows how to use these two keywords in your DDS. Indicators are not valid with either of these two. Because hex pairs always appear in twos, make sure that the field is defined with an even length. The TRNSPY (Transparency) keyword prevents OS/400 from interpreting the contents of the field into printable characters and the CVTDTA (Convert Data) keyword tells OS/400 to convert the contents of the field into machine-understandable hexadecimal data when passing it to the printer.
You’ve come a great way in a short amount of time and are just about finished.
The RPG IV Program
The RPG IV code in Figure 3 uses the methods above to control the fonts of an IP- connected HP LaserJet printer. Start off by defining the two parts of the PCL command as two separate constants. This will keep the size of the constant to one line and allow you to define multiple font attributes for later use. In the calculation specs, EVAL is used to concatenate the two parts together and place the completed PCL command into the field that has the TRNSPY and CVTDTA keywords. The field receiving the concatenated data is longer than it needs to be, and this presents an unexpected challenge.
Because OS/400 will attempt to translate the entire contents of the field containing the PCL command, it is very important to send only valid hex pairs to the printer. Invalid data will be translated as garbage, and the printer won’t know what to do with the command. Spaces, as it turns out, are not valid hexadecimal digits, but zeros are. So, if you’re dynamically building the contents of the data field, like the example in Figure 3, change any residual spaces to zeros. The RPG command XLATE will accomplish the conversion very nicely.
Watch Your Step, Please
When changing the font from the default font, be aware that some of the fonts and point sizes are proportional. This implies that the spacing is also proportional, so take care how your print file is laid out. If you have the luxury, keeping the special fonts on separate lines will provide you with a good mechanism for managing the proportional spacing. The space between print lines still needs to be controlled by SPACEA and SPACEB. Keep in mind that the larger the point size specified, the more the printed text will encroach on the text lines above and below. This is also a good time to reiterate the other warnings I stated before. Make sure that the field containing the PCL command is large enough to contain all the hex pairs that make up the translated command, and if the field is generously sized, convert any residual spaces to zeros.
Fonts to the Masses
Now you are able to overcome the SCS limitation for fonts. You have a powerful technique for passing a font PCL command to the printer. Using the same method, other PCL commands could also be sent to the printer. Be brave, and experiment with this powerful tool. Explore the different fonts available on the HP LaserJet printer, spruce up some of those sagging reports, and create new ones. Certificates, invoices, and statements are now possible and can be printed over the LAN to the IP-connected HP LaserJet printer. One last thought: This method could also be used to send other PCL commands to the printer. I wonder if there are any that may be appropriate. Hmmmm.
0 1 2 3 4 5 6 7 8 9 A B C D E F
0 NUL SOH STX ETX EOT ENQ ACK BEL BS HT LF VT FF CR SO SI
1 DLE DC1 DC2 DC3 DC4 NAK SYN ETB CAN EM SUB ESC FS GS RS US
2 SP ! “ # $ % & ‘ ( ) * + , - . /
3 0 1 2 3 4 5 6 7 8 9 : ; < = > ?
4 @ A B C D E F G H I J K L M N O
5 P Q R S T U V W X Y Z [ ] ^ _
6 ` a b c d e f g h I j k l m n o
7 p q r s t u v w x y z { | } ~ DEL
Figure 1: Using this chart, you can translate PCL commands into hex.
A R TRAVCERT
A SKIPB(001)
A PRTCMD1 132A 1
A TRNSPY CVTDTA
A 20'Travel Certificate'
A SPACEB(006)
A PRTCMD2 132A 1
A TRNSPY CVTDTA
A 15'One Thousand Two Hundred Dollars'
A SPACEB(003)
A PRTCMD3 132A 1
A TRNSPY CVTDTA
A 20'Love, Uncle Bob and Aunt Sue'
A SPACEB(003)
Figure 2: This DDS is an example of using TRNSPY and CVTDTA.
FFONTPRT O E PRINTER OFLIND(*In31)
* Basic ASCII symbol/character set
D SymSet C '1B28313055'
* Font CG Times, Bold, 36 Point -
D Cg36P C '1B28733170333676307333623431303154'
* Font CG Times, Normal, 20 Point -
D Cg20P C '1B28733170323076307330623431303154'
* Font Coronet, Normal, 24 Point -
D Cn24P C '1B28733170323476317330623431313654'
* Concatenate the symbol set together with the font attributes
C EVAL PrtCmd1 = SymSet + Cg36P
C EVAL PrtCmd2 = SymSet + Cg20P
C EVAL PrtCmd3 = SymSet + Cn24P
* Convert any spaces to zeros
C ' ':'0' XLATE PrtCmd1 PrtCmd1
C ' ':'0' XLATE PrtCmd2 PrtCmd2
C ' ':'0' XLATE PrtCmd3 PrtCmd3
* Print
C WRITE TRAVCERT
C EVAL *InLR = *On
Figure 3: The RPG IV source drives font commands and printing.
LATEST COMMENTS
MC Press Online