R 66,T 5 BoxFont - A Line Draw Font for PostScript written by Glenn Claudi-Magnussen [74017,1407] INTRODUCTION This document describes how I created a special font for line draw characters in PostScript. Because this involved changing three existing Sprint files, not the creation of any new file, I have embedded the changed/new lines into this document, along with a description of the changes and what they do (this results in a much smaller file than if I were to upload modified versions of each file). To make the changes to your own files (backups, of course), you can use Sprint's cut and paste capabilities to copy the sections from this file into your files. First, a little background. The PostScript printer I am using (actually, a Laser Jet II with a JetScript board) doesn't have any fonts with line drawing characters, so I started looking into how to implement line draw for PostScript using Sprint. What I ended up doing was creating and downloading a new font with the characters I wanted, and using Sprint's translation character table to switch to this font for printing these characters. I have also used this same approach for creating lots of other special characters which I wanted. The three files which need to be changed are POSTSCR.SPL, POSTSCR.HDR, and POSTSCR.TCT. POSTSCR.SPL is changed to add the new font (and some attributes - more on this later). Sprint must be re-installed with the POSTSCR.SPL file before anything can be printed with the new font. POSTSCR.HDR is changed to set up the new font. POSTSCR.HDR is a file written in PostScript language which is downloaded to the printer before a file is printed. The additions to this file are written in PostScript. POSTSCR.TCT is modified to cause the line draw characters to be mapped to this new font. Some other changes were made to this file to eliminate some problems when text and line draw characters are mixed together - see explanation below. HOW IT'S USED Once the required changes have been made, the line draw characters can be used anywhere in a document. One thing to consider is that the line draw characters are monospaced (they all have the same width) and should be used with a monospaced font of the same size if columns are expected to line up. Depending on what you are doing, you can get around this by using tabs, which will cause columns to line up regardless of what's to the left of them. The only monospaced font my printer has is Courier, so I made my characters the same width as Courier characters (width = 0.6 x height). I've used a proportional spaced font for documents, switching to Courier only for tables, etc. For example: This can be in Times-Roman This would be in Courier This can be Times-Roman This can be in Times-Roman HOW IT WORKS The new characters exist in a font called BoxFont. If you call up the list of fonts, you'll see BoxFont there. When Sprint prints a document, POSTSCR.HDR is sent to the printer first, and the changes described add the information the printer needs to print this font. Even though these characters exist only in this new font, you don't have to specifically call out this font - the additions to POSTSCR.TCT cause these characters to be translated to BoxFont regardless of the current font. This makes the use of line draw characters more or less transparent. SOME OTHER CONSIDERATIONS You will notice that printing is noticeably slower if you have a lot of line draw characters. I assume this is because it's doing a character translation for each line draw character it comes across. Also, if you have a lot of line draw characters on a page you may get an Out of Memory 70 error when printing. This is because each character translation is temporarily taking up a certain amount of memory as the page is formatted. The way to get around this is to select areas which consist only of line draw characters and spaces and set the font to BoxFont for that area. When the font is already defined as BoxFont, Sprint doesn't use up memory to translate the characters to BoxFont. So your table might look like this: Leave area with text in regular font (Courier) FONT BoxFont Because of the way Sprint handles spaces and tabs, things sometimes don't quite line up when "oddball" point sizes (e.g., 9.5 point) are used. For this reason I added my own space character (I use character #128). If things aren't lining up, I replace all the spaces in the table with this character. If you find yourself creating your own special characters like I did, you might want to download the program FONTEDIT from the PC magazine forum. It allows you to modify the way characters are displayed on your EGA or VGA screen. That way you won't have to look at all the funny characters (e.g., ) in the standard character set. COMMENTS First of all, thanks to everyone here on the forum and at Borland technical support who have helped me overcome some of the hurdles in getting this working. I'm still working on making a few changes. One of the things I've been thinking of doing is adding the normal character set to BoxFont by copying them from an existing font such as Courier. By doing this the character translations could be eliminated (you would just select BoxFont as the font for anything which needs line drawing characters), which would speed up the printing and eliminate the Out of Memory 70 problems. So far I've figured how to copy an existing font to a new font, but I haven't figured out how to then redefine some of the characters. I'll be glad to answer any questions anyone has, and I welcome any comments or suggestions. ----------------------------------------------------------------- Below are the changes to the three files, POSTSCR.SPL, POSTSCR.HDR, and POSTSCR.TCT. I have embedded a number of comments to explain some things about these changes. My comments are on lines which begin with "##". Don't copy these comments into your files. ## CHANGES TO POSTSCR.SPL ## find the following line in the file: ## font Times,on /Times-Roman %d ff\ ,pst Times-Roman ## and add the following after it: font BoxFont,on /Box-Font %d ff\ ,width 180 ## find the following line in the file: ## attr gray,on 0.5 setgray\ ,off 0 setgray\ ## and add the following after it: attr gray1,on 0.75 setgray\ ,off 0 setgray\ attr gray2,on 0.5 setgray\ ,off 0 setgray\ attr gray3,on 0.25 setgray\ ,off 0 setgray\ ## CHANGES TO POSTSCR.HDR ## find the following line near the bottom of the file: ## initgraphics ## and add the following BEFORE it: % Begin BoxFont definition /newfont 120 dict def newfont begin /FontType 3 def /FontMatrix [.001 0 0 .001 0 0] def /FontBBox [0 0 600 1000] def % Encoding array: /Encoding 256 array def 0 1 255 {Encoding exch /.notdef put} for Encoding 128 /hspace put Encoding 202 /AAA put Encoding 203 /BBB put Encoding 204 /CCC put Encoding 205 /DDD put Encoding 206 /EEE put Encoding 207 /FFF put Encoding 208 /GGG put Encoding 209 /HHH put Encoding 210 /III put Encoding 211 /JJJ put Encoding 212 /KKK put Encoding 213 /LLL put Encoding 214 /MMM put Encoding 215 /NNN put Encoding 216 /OOO put Encoding 217 /lowright put Encoding 218 /upleft put Encoding 219 /RRR put Encoding 176 /gray1 put Encoding 177 /gray2 put Encoding 178 /gray3 put Encoding 179 /vert put Encoding 180 /edgeright put Encoding 181 /fff put Encoding 182 /ggg put Encoding 183 /hhh put Encoding 184 /iii put Encoding 185 /jjj put Encoding 186 /kkk put Encoding 187 /lll put Encoding 188 /mmm put Encoding 189 /nnn put Encoding 190 /ooo put Encoding 191 /upright put Encoding 192 /lowleft put Encoding 193 /edgebottom put Encoding 194 /edgetop put Encoding 195 /edgeleft put Encoding 196 /horiz put Encoding 197 /cross put Encoding 198 /www put Encoding 199 /xxx put Encoding 200 /yyy put Encoding 201 /zzz put % Character descriptions: % Note that lines are created with a filled polygon rather % than just a line. This way the line thickness increases % proportionately with the point size. /CharProcs 46 dict def CharProcs begin /.notdef {} def /upleft {290 0 moveto 290 510 lineto 600 510 lineto 600 490 lineto 310 490 lineto 310 0 lineto closepath fill} def /lowleft {290 1000 moveto 290 490 lineto 600 490 lineto 600 510 lineto 310 510 lineto 310 1000 lineto closepath fill} def /upright {0 510 moveto 310 510 lineto 310 0 lineto 290 0 lineto 290 490 lineto 0 490 lineto closepath fill} def /lowright {0 490 moveto 310 490 lineto 310 1000 lineto 290 1000 lineto 290 510 lineto 0 510 lineto closepath fill} def /vert {290 0 moveto 290 1000 lineto 310 1000 lineto 310 0 lineto closepath fill} def /horiz {0 490 moveto 600 490 lineto 600 510 lineto 0 510 lineto closepath fill} def /edgeleft {290 0 moveto 290 1000 lineto 310 1000 lineto 310 510 lineto 600 510 lineto 600 490 lineto 310 490 lineto 310 0 lineto closepath fill} def /edgeright {310 0 moveto 310 1000 lineto 290 1000 lineto 290 510 lineto 0 510 lineto 0 490 lineto 290 490 lineto 290 0 lineto closepath fill} def /edgetop {0 510 moveto 600 510 lineto 600 490 lineto 310 490 lineto 310 0 lineto 290 0 lineto 290 490 lineto 0 490 lineto closepath fill} def /edgebottom {0 490 moveto 600 490 lineto 600 510 lineto 310 510 lineto 310 1000 lineto 290 1000 lineto 290 510 lineto 0 510 lineto closepath fill} def /cross {290 0 moveto 290 1000 lineto 310 1000 lineto 310 0 lineto closepath fill 0 490 moveto 0 510 lineto 600 510 lineto 600 490 lineto closepath fill} def /hspace {0 0 moveto 600 1000 moveto stroke} def /AAA {0 610 moveto 190 610 lineto 190 1000 lineto 210 1000 lineto 210 590 lineto 0 590 lineto closepath fill 390 1000 moveto 390 590 lineto 600 590 lineto 600 610 lineto 410 610 lineto 410 1000 lineto closepath fill 0 390 moveto 600 390 lineto 600 410 lineto 0 410 lineto closepath fill} def /BBB {0 610 moveto 600 610 lineto 600 590 lineto 0 590 lineto closepath fill 0 410 moveto 210 410 lineto 210 0 lineto 190 0 lineto 190 390 lineto 0 390 lineto closepath fill 390 0 moveto 390 410 lineto 600 410 lineto 600 390 lineto 410 390 lineto 410 0 lineto closepath fill} def /CCC {210 0 moveto 210 1000 lineto 190 1000 lineto 190 0 lineto closepath fill 390 0 moveto 390 410 lineto 600 410 lineto 600 390 lineto 410 390 lineto 410 0 lineto closepath fill 390 1000 moveto 390 590 lineto 600 590 lineto 600 610 lineto 410 610 lineto 410 1000 lineto closepath fill} def /DDD {0 610 moveto 600 610 lineto 600 590 lineto 0 590 lineto closepath fill 0 410 moveto 600 410 lineto 600 390 lineto 0 390 lineto closepath fill} def /EEE {0 590 moveto 210 590 lineto 210 1000 lineto 190 1000 lineto 190 610 lineto 0 610 lineto closepath fill 390 1000 moveto 390 590 lineto 600 590 lineto 600 610 lineto 410 610 lineto 410 1000 lineto closepath fill 600 410 moveto 390 410 lineto 390 0 lineto 410 0 lineto 410 390 lineto 600 390 lineto closepath fill 0 410 moveto 210 410 lineto 210 0 lineto 190 0 lineto 190 390 lineto 0 390 lineto closepath fill} def /FFF {0 410 moveto 600 410 lineto 600 390 lineto 0 390 lineto closepath fill 0 610 moveto 600 610 lineto 600 590 lineto 0 590 lineto closepath fill 290 610 moveto 290 1000 lineto 310 1000 lineto 310 610 lineto closepath fill} def /GGG {0 510 moveto 600 510 lineto 600 490 lineto 0 490 lineto closepath fill 190 510 moveto 190 1000 lineto 210 1000 lineto 210 510 lineto closepath fill 390 510 moveto 390 1000 lineto 410 1000 lineto 410 510 lineto closepath fill} def /HHH {0 410 moveto 600 410 lineto 600 390 lineto 0 390 lineto closepath fill 0 610 moveto 600 610 lineto 600 590 lineto 0 590 lineto closepath fill 290 390 moveto 290 0 lineto 310 0 lineto 310 390 lineto closepath fill} def /III {0 510 moveto 600 510 lineto 600 490 lineto 0 490 lineto closepath fill 190 490 moveto 190 0 lineto 210 0 lineto 210 490 lineto closepath fill 390 490 moveto 390 0 lineto 410 0 lineto 410 490 lineto closepath fill} def /JJJ {190 1000 moveto 190 490 lineto 600 490 lineto 600 510 lineto 210 510 lineto 210 1000 lineto closepath fill 390 1000 moveto 390 510 lineto 410 510 lineto 410 1000 lineto closepath fill} def /KKK {290 1000 moveto 290 390 lineto 600 390 lineto 600 410 lineto 310 410 lineto 310 1000 lineto closepath fill 310 590 moveto 600 590 lineto 600 610 lineto 310 610 lineto closepath fill} def /LLL {290 0 moveto 290 610 lineto 600 610 lineto 600 590 lineto 310 590 lineto 310 0 lineto closepath fill 310 410 moveto 600 410 lineto 600 390 lineto 310 390 lineto closepath fill} def /MMM {190 0 moveto 190 510 lineto 600 510 lineto 600 490 lineto 210 490 lineto 210 0 lineto closepath fill 390 0 moveto 390 490 lineto 410 490 lineto 410 0 lineto closepath fill} def /NNN {190 0 moveto 190 1000 lineto 210 1000 lineto 210 0 lineto closepath fill 390 0 moveto 390 1000 lineto 410 1000 lineto 410 0 lineto closepath fill 0 490 moveto 600 490 lineto 600 510 lineto 0 510 lineto closepath fill} def /OOO {290 0 moveto 290 1000 lineto 310 1000 lineto 310 0 lineto closepath fill 0 390 moveto 600 390 lineto 600 410 lineto 0 410 lineto closepath fill 0 590 moveto 600 590 lineto 600 610 lineto 0 610 lineto closepath fill} def /RRR {0 0 moveto 0 1000 lineto 600 1000 lineto 600 0 lineto closepath fill} def /gray1 {0 0 moveto 0 1000 lineto 600 1000 lineto 600 0 lineto closepath fill} def /gray2 {0 0 moveto 0 1000 lineto 600 1000 lineto 600 0 lineto closepath fill} def /gray3 {0 0 moveto 0 1000 lineto 600 1000 lineto 600 0 lineto closepath fill} def /fff {290 0 moveto 290 1000 lineto 310 1000 lineto 310 0 lineto closepath fill 0 390 moveto 290 390 lineto 290 410 lineto 0 410 lineto closepath fill 0 590 moveto 290 590 lineto 290 610 lineto 0 610 lineto closepath fill} def /ggg {190 0 moveto 190 1000 lineto 210 1000 lineto 210 0 lineto closepath fill 390 0 moveto 390 1000 lineto 410 1000 lineto 410 0 lineto closepath fill 0 490 moveto 190 490 lineto 190 510 lineto 0 510 lineto closepath fill} def /hhh {0 510 moveto 410 510 lineto 410 0 lineto 390 0 lineto 390 490 lineto 0 490 lineto closepath fill 190 490 moveto 190 0 lineto 210 0 lineto 210 490 lineto closepath fill} def /iii {0 610 moveto 310 610 lineto 310 0 lineto 290 0 lineto 290 590 lineto 0 590 lineto closepath fill 0 410 moveto 290 410 lineto 290 390 lineto 0 390 lineto closepath fill} def /jjj {0 590 moveto 210 590 lineto 210 1000 lineto 190 1000 lineto 190 610 lineto 0 610 lineto closepath fill 0 410 moveto 210 410 lineto 210 0 lineto 190 0 lineto 190 390 lineto 0 390 lineto closepath fill 390 0 moveto 390 1000 lineto 410 1000 lineto 410 0 lineto closepath fill} def /kkk {190 0 moveto 190 1000 lineto 210 1000 lineto 210 0 lineto closepath fill 390 0 moveto 390 1000 lineto 410 1000 lineto 410 0 lineto closepath fill} def /lll {0 610 moveto 410 610 lineto 410 0 lineto 390 0 lineto 390 590 lineto 0 590 lineto closepath fill 0 410 moveto 210 410 lineto 210 0 lineto 190 0 lineto 190 390 lineto 0 390 lineto closepath fill} def /mmm {0 590 moveto 210 590 lineto 210 1000 lineto 190 1000 lineto 190 610 lineto 0 610 lineto closepath fill 0 390 moveto 410 390 lineto 410 1000 lineto 390 1000 lineto 390 410 lineto 0 410 lineto closepath fill} def /nnn {0 490 moveto 410 490 lineto 410 1000 lineto 390 1000 lineto 390 510 lineto 0 510 lineto closepath fill 190 510 moveto 190 1000 lineto 210 1000 lineto 210 510 lineto closepath fill} def /ooo {0 390 moveto 310 390 lineto 310 1000 lineto 290 1000 lineto 290 410 lineto 0 410 lineto closepath fill 0 590 moveto 290 590 lineto 290 610 lineto 0 610 lineto closepath fill} def /www {290 0 moveto 290 1000 lineto 310 1000 lineto 310 0 lineto closepath fill 310 390 moveto 600 390 lineto 600 410 lineto 310 410 lineto closepath fill 310 590 moveto 600 590 lineto 600 610 lineto 310 610 lineto closepath fill} def /xxx {190 0 moveto 190 1000 lineto 210 1000 lineto 210 0 lineto closepath fill 390 0 moveto 390 1000 lineto 410 1000 lineto 410 0 lineto closepath fill 410 490 moveto 600 490 lineto 600 510 lineto 410 510 lineto closepath fill} def /yyy {190 1000 moveto 190 390 lineto 600 390 lineto 600 410 lineto 210 410 lineto 210 1000 lineto closepath fill 390 1000 moveto 390 590 lineto 600 590 lineto 600 610 lineto 410 610 lineto 410 1000 lineto closepath fill} def /zzz {190 0 moveto 190 610 lineto 600 610 lineto 600 590 lineto 210 590 lineto 210 0 lineto closepath fill 390 0 moveto 390 410 lineto 600 410 lineto 600 390 lineto 410 390 lineto 410 0 lineto closepath fill} def /BuildChar {600 0 0 0 600 1000 setcachedevice exch begin Encoding exch get CharProcs exch get end exec } def /Box-Font newfont definefont pop % End box font definition ## CHANGES TO POSTSCR.TCT: ## locate the following line near the top of the file: ## @macro(sym() "@symbol(@char(@eval))") ## and add the following lines after it: @macro(bchar() "@BoxFont(@char(@eval))") @macro(g1char() "@gray1(@BoxFont(@char(@eval)))") @macro(g2char() "@gray2(@BoxFont(@char(@eval)))") @macro(g3char() "@gray3(@BoxFont(@char(@eval)))") ## Locate the following @tct commands and change them as shown. ## These changes inhibit the character translations if the current ## font is Courier, so the Courier font will be truly monospaced ## and everything will line up. These changes are optional, but ## recommended: @if(plain,else { @tct("fi" "@case(font, courier, symbol "fi", else "@char(0aeh)")") @tct("fl" "@case(font, courier, symbol "fl", else "@char(0afh)")") @tct('AT' '@case(font, courier 'AT', else 'A@hsp(-0.12 em)T')') @tct('AV' '@case(font, courier 'AV', else 'A@hsp(-0.14 em)V')') @tct('AW' '@case(font, courier 'AW', else 'A@hsp(-0.10 em)W')') @tct('AY' '@case(font, courier 'AY', else 'A@hsp(-0.12 em)Y')') @tct('Av' '@case(font, courier 'Av', else 'A@hsp(-0.08 em)v')') @tct('Aw' '@case(font, courier 'Aw', else 'A@hsp(-0.08 em)w')') @tct('Ay' '@case(font, courier 'Ay', else 'A@hsp(-0.08 em)y')') @tct('FA' '@case(font, courier 'FA', else 'F@hsp(-0.10 em)A')') @tct('Fa' '@case(font, courier 'Fa', else 'F@hsp(-0.03 em)a')') @tct('Fo' '@case(font, courier 'Fo', else 'F@hsp(-0.05 em)o')') @tct('LV' '@case(font, courier 'LV', else 'L@hsp(-0.12 em)V')') @tct('LW' '@case(font, courier 'LW', else 'L@hsp(-0.10 em)W')') @tct('LY' '@case(font, courier 'LY', else 'L@hsp(-0.20 em)Y')') @tct('PA' '@case(font, courier 'PA', else 'P@hsp(-0.15 em)A')') @tct('Pa' '@case(font, courier 'Pa', else 'P@hsp(-0.03 em)a')') @tct('Pe' '@case(font, courier 'Pe', else 'P@hsp(-0.03 em)e')') @tct('Po' '@case(font, courier 'Po', else 'P@hsp(-0.05 em)o')') @tct('TA' '@case(font, courier 'TA', else 'T@hsp(-0.07 em)A')') @tct('Ta' '@case(font, courier 'Ta', else 'T@hsp(-0.07 em)a')') @tct('Te' '@case(font, courier 'Te', else 'T@hsp(-0.07 em)e')') @tct('To' '@case(font, courier 'To', else 'T@hsp(-0.07 em)o')') @tct('Tu' '@case(font, courier 'Tu', else 'T@hsp(-0.07 em)u')') @tct('Ty' '@case(font, courier 'Ty', else 'T@hsp(-0.07 em)y')') @tct('VA' '@case(font, courier 'VA', else 'V@hsp(-0.13 em)A')') @tct('VO' '@case(font, courier 'VO', else 'V@hsp(-0.08 em)O')') @tct('Va' '@case(font, courier 'Va', else 'V@hsp(-0.08 em)a')') @tct('Ve' '@case(font, courier 'Ve', else 'V@hsp(-0.08 em)e')') @tct('Vo' '@case(font, courier 'Vo', else 'V@hsp(-0.08 em)o')') @tct('WA' '@case(font, courier 'WA', else 'W@hsp(-0.10 em)A')') @tct('WO' '@case(font, courier 'WO', else 'W@hsp(-0.05 em)O')') @tct('Wa' '@case(font, courier 'Wa', else 'W@hsp(-0.08 em)a')') @tct('We' '@case(font, courier 'We', else 'W@hsp(-0.08 em)e')') @tct('Wo' '@case(font, courier 'Wo', else 'W@hsp(-0.08 em)o')') @tct('YA' '@case(font, courier 'YA', else 'Y@hsp(-0.15 em)A')') @tct('YO' '@case(font, courier 'YO', else 'Y@hsp(-0.08 em)O')') @tct('Ya' '@case(font, courier 'Ya', else 'Y@hsp(-0.16 em)a')') @tct('Ye' '@case(font, courier 'Ye', else 'Y@hsp(-0.16 em)e')') @tct('Yo' '@case(font, courier 'Yo', else 'Y@hsp(-0.16 em)o')') ## Add the following character translations below the ones above. @tct( "@g1char(0b0h)") @tct( "@g2char(0b1h)") @tct( "@g3char(0b2h)") @tct( "@bchar(0b3h)") @tct( "@bchar(0b4h)") @tct( "@bchar(0b5h)") @tct( "@bchar(0b6h)") @tct( "@bchar(0b7h)") @tct( "@bchar(0b8h)") @tct( "@bchar(0b9h)") @tct( "@bchar(0bah)") @tct( "@bchar(0bbh)") @tct( "@bchar(0bch)") @tct( "@bchar(0bdh)") @tct( "@bchar(0beh)") @tct( "@bchar(0bfh)") @tct( "@bchar(0c0h)") @tct( "@bchar(0c1h)") @tct( "@bchar(0c2h)") @tct( "@bchar(0c3h)") @tct( "@bchar(0c4h)") @tct( "@bchar(0c5h)") @tct( "@bchar(0c6h)") @tct( "@bchar(0c7h)") @tct( "@bchar(0c8h)") @tct( "@bchar(0c9h)") @tct( "@bchar(0cah)") @tct( "@bchar(0cbh)") @tct( "@bchar(0cch)") @tct( "@bchar(0cdh)") @tct( "@bchar(0ceh)") @tct( "@bchar(0cfh)") @tct( "@bchar(0d0h)") @tct( "@bchar(0d1h)") @tct( "@bchar(0d2h)") @tct( "@bchar(0d3h)") @tct( "@bchar(0d4h)") @tct( "@bchar(0d5h)") @tct( "@bchar(0d6h)") @tct( "@bchar(0d7h)") @tct( "@bchar(0d8h)") @tct( "@bchar(0d9h)") @tct( "@bchar(0dah)") @tct( "@bchar(0dbh)")