THE FOLLOWING IS AN ARTICLE WRITTEN BY RICHARD ELLIOTT IN THE JANUARY ISSUE OF THE "PINTER FOXPRO NEWSLETTER" PUBLISHED BY: PINTER CONSULTING P.O. BOX 1324 MENLO PARK, CA 94026-1324 (415) 325-7953 ----------------------------------------------------------------- I bought Les Pinter's book, Foxpro Programming just to get my hands on the Laserjet library. It was worth it for those routines alone. Since then I have updated the library (added a few routines of my own and revised others) to take better advantage of the Foxpro environment. The original library could work in either Foxbase or Foxpro, but my revised version in Foxpro only. Basically what I did was to convert all of the procedures to variables or functions, and the way I got away with it was to use the ??? output command. What makes this command useful is that it implicetly uses the SET PRINTER ON and SET PRINTER OFF so you don't have to. The old way would be to do something like this: PROCEDURE SET PRINTER ON ?? printer_command SET PRINTER OFF RETURN By using the ??? command all you have to do is: ??? printer_command You can create any number of printer commands as variables, including long strings. The only time this will not work is where you need to pass a parameter (such as lines per inch, etc.). In this case a function works better than procedure. Why? Because it can be called with ???. For example, with the previous library you would use: DO shading WITH 2,4,3,5,10 While using a function you could say: ??? SHADING(2,4,3,5,10) What's the advantage? For one the function is slightly smaller and slightly faster. (see full listing). But the real advantage comes in the versatility of functions. You even can capture the output to a variable. For example: DO shading WITH 2,4,3,5,10 DO box WITH 2,4,3,5,10 Is the same as: ??? SHADING(2,4,3,5,10) ??? BOX(2,4,3,5,10) Or: ??? SHADING(2,4,3,5,10) + BOX(2,4,3,5,10) Or: shade_box = SHADING(2,4,3,5,10) + BOX(2,4,3,5,10) ??? shade_box Notice how multiple functions can also be called on the same line. By capturing the output of the function to a variable you can now output it over and over again without calling the functions. On simple reports this would not save much time, but for complex multi-page and multi-copy forms it can really be a time saver. You could even capture a whole form to a memo field and fill it out with the SAYIT(), SOFTFONT() and INTERNAL() functions being the only ones called in the code. Preset a whole forms library in memo fields and you've got it made! One other major change I made was to declare most of the internal font management printer escape sequences as variables. This provides more versatility in my opinion than the DO INTERNAL WITH or the INTERNAL() function. For example I could set a compressed landscape internal font with: ??? INTERNAL(5) Or with: ??? landscape + pitch_17 If the page is already set to landscape mode, you don't even need the landscape variable. I find the latter more readable and easier to customize. For example, I sometimes use the other symbol sets and with the INTERNAL() function on my HP Laserjet IIP I would need to expand the options to include 35 different combinations, not just the six included here. The one disadvantage of this approach is that it is possible to combine the printer variables in combinations that do not work or provide the expected results. The printer will usually ignore these combinations and maintain the last default. This boils down to one of personal preference (and availability of memory variable space!). That is why both are included here. Another change was replacing the POSITION procedure with my SAYIT() function. I added a PICTURE parameter for numbers and built in type checking so you can pass numbers, dates and logical values without converting the to character. The function does the dirty work for you. The last major change was the addition of a font loader function. This simply copies a font file (such as those made by Bitsream Fontware) with appropriate commands. I tried copying the fonts directly from memo fields, but that didn't seem to work unless I first copied the memo field to a long string variable. If I set MVARSIZE = 64 in my CONFIG.FP file I can print memo field stored font files up to 64K in size (around 30 points, depending on the typeface). Unfortunately this eats up memory, so I'd rather keep the fonts on the disk. By the way, all you Deskjet owners out there, the font management routines here will work just fine for you as well. The box, line, grid and shading routines will not work (but will not crash the printer, it just ignores them). I own a Deskjet as well so I can testify to that! There are three sample .PRG files. The first, REPORT1A.PRG is a modified version of the one provided with the original LASERLIB.PRG library to show the differences. The remaining 2, INVOICE1.PRG and INVOICE2.PRG provide a sample invoice printed with soft fonts and internal fonts repectively. If you get the disk subscription as well, the soft fonts on the disk are courtesy of: Swifte International, Ltd. Stone Mill Office park 724 Yorklyn Rd. Hockessin, DE 19707 (800) 237-9383 Swifte provides a good font management and font creation system for those on a budget. Demos are available on BBSs everywhere, and they offer a 30 day money back guarantee. Richard Elliott Ferret Software 1102 Burwick Drive Herndon, VA 22070 (703) 742-8266