Consultor Eletrônico



Kbase P17330: How to print to a postscript printer from 4GL?
Autor   Progress Software Corporation - Progress
Acesso   Público
Publicação   29/01/2003
Status: Unverified

SYMPTOM(s):

How to print to a postscript printer from 4GL?

FIX:

The information provided pertains to the OUTPUT TO PRINTER option
only and includes POSTSCRIPT printing as well.

From the PROGRESS 4GL, there are only two ways to enable printing
using POSTSCRIPT printers, which makes the use of POSTSCRIPT printers
less flexible than NON-POSTSCRIPT using ESCAPE sequences. This is
due to the technical requirements intoduced when printing to a
POSTSCRIPT printer. In Windows, it is necessary to send the correct
sequences to the POSTSCRIPT printer before anything else can happen,
otherwise the POSTSCRIPT commands will not be correctly understood.

Using the -wpp and -wplf Startup Command Line Options

The -wpp option stands for Windows Passthrough Printing. Using this
startup option automatically forces the PROGRESS print method to
assume that when the 4GL issues an OUTPUT TO PRINTER or OUTPUT TO LPTn
statement, it wishes to send output directly to the printer, bypassing
any Windows print handling.

This applies to both POSTSCRIPT and NON-POSTSCRIPT printers.

The drawback to the startup-option approach is that it does not allow
the programmer to utilize different print methods within the same
PROGRESS session: it's an "all or nothing" proposition. (Otherwise,
Windows would interpret the ESCAPE sequences used in other printing
approaches as wacky characters.)

The -wplf option stands for Windows Passthrough Line Feed. This
option is similar to -wpp except that for NON-POSTSCRIPT printers,
when a new line is sent to the printer, only the line feed character
is sent, not the usual carriage-return/line-feed pair. It also
enables the Passthrough mode automatically. Its drawbacks are the
same as with the -wpp mode, described above.

Initializing the Printer

This is the most complex portion of the printer code. When the 4GL
detects an OUTPUT TO PRINTER or OUTPUT TO LPTn statement, the core
transfers control to the PROGRESS Windows print driver. An OPEN call
first takes a look at the persistent printer flags in case there have
to be some temporary changes. From there, processing differs
depending on whether the 4GL sent an OUTPUT TO PRINTER or OUTPUT TO
LPTn statement.


* Phase 1: OUTPUT TO PRINTER only

If OUTPUT TO PRINTER is specified, PROGRESS first looks at the
:PRINTER-CONTROL-HANDLE attribute of the SESSION handle (this is
available in Version 7.3A and higher). This enables 4GL
programmers to place a Print Setup button or menu option into
their applications, for example, as an affordance using the
SYSTEM-DIALOG PRINT-SETUP statement. If the :PRINTER-CONTROL-HANDLE
contains a value, that information is used to obtain the current
printer context. If the :PRINTER-CONTROL-HANDLE is zero, or if
the PROGRESS version is 7.2E01 or later, the WIN.INI file is scanned for
the "device=" line in the [windows] section. If there is no
"device=" line, an error is returned. Otherwise, Windows is
queried to create a printer context for the specified printer.

Once the printer context has been created, the PROGRESS.INI file
is queried for a PrinterFont setting in the [Startup] section. If
no font is specified, then nothing is done to change the default
font, and PROGRESS uses the current printer context to print with
the printer's default font. (Consult the manual for the target
printer to learn how to control this feature from the printer
side.)

If the PROGRESS.INI indicates that a different default font is
specified, then the string is parsed the same way as with the
settings in the [Fonts] section. If a SIZE is specified on the
font definition, it is assumed to be specified in "display" units.
PROGRESS converts it to "printer logical" units. The font is then
created and the printer context is notified to use the new font.


* Phase 1: OUTPUT TO LPTn only

If OUTPUT TO LPTn is indicated, PROGRESS searches the WIN.INI file
for the first entry in the [Print.erPorts] section that matches the
specified port name, for example, LPT1. If there is no match,
then an error is returned. If there is a match, the printer
information is taken from the matching line and a printer context
is created.

Next, PROGRESS queries the PROGRESS.INI file for the PrinterFontn
setting in the [Startup] section. If no font is specified, then
a font structure is created based on the COURIER NEW font. The
height of this font is calculated based on the vertical printer
resolution and the height of a line, with a goal of 60 lines per
page. If a PtinerFontn *is* specified, then that font information
is used to create a font. Either way, the printer context is then
notified to use the new font.


* Phase 2: OUTPUT TO PRINTER and OUTPUT TO LPTn

Once the printer context and printer font information have been
sorted out, the next series of steps prepare the printer to receive
the correct input.

a. The printer is queried to determine the size of the height
and widthof a single line. This is used for carriage-return/line-
feed (CR/LF) handling.

b. PROGRESS sets the starting printer row. Depending on
whether OUTPUT TO PRINTER or OUTPUT TO LPTn is indicated, this
starting row differs. If using OUTPUT TO PRINTER, the starting
row is set to 0. If using OUTPUT TO LPTn, the starting row is
set = (1.5 * <printer row height>).

c. PROGRESS determines whether the destination printer is a
POSTSCRIPT printer. This information is flagged for later.

d. PROGRESS looks to see whether the PAGE SIZE 0 phrase has been
used with the OUTPUT TO statement. Use of the PAGE SIZE 0 phrase
indicates that the 4GL code intends to handle all output and
formatting information for this particular printout. (Essentially,
it is like setting -wpp on the command line but without the
drawback of having -wpp apply to the entire session.) If PAGE
SIZE 0 is indicated, the PASSTHROUGH flag is set. This flag will
be checked a little bit later.

e. PROGRESS queries the window title of the window which currently
has focus. This title is used as the job name when generating the
printout.

f. PROGRESS checks the POSTSCRIPT and PASSTHROUGH flags, which
might have been set in steps c. and d., respectively.

If BOTH are set, PROGRESS makes the appropriate call to Windows
in order to disable Windows handling of POSTSCRIPT printers (since
the PASSTHROUGH flag indicates that the 4GL code will be handling
all of the POSTSCRIPT output.)

If one but not both is set, then a normal print job is created.

Initialization is now complete, so now printer output can begin.


Accepting Printer Output

There are three different ways to send data to a printer driver: a
character at a time, a string at a time, or by using PUT CONTROL to
send NULL characters to the printer. Each of these behaves
differently depending on the state of the POSTSCRIPT and PASSTHROUGH
flags, either of which may have been set in the initialization phase
above.


* Outputting a CHARACTER

a. When a character is being output, PROGRESS first checks to see
if it is a line-feed (LF) character. If so, we check for whether
PASSTHROUGH mode is indicated. In PASSTHROUGH mode, PROGRESS sends
three characters to the printer directly: a carriage return (CR),
a LF, and a NULL character. (However, if the -wplf startup option
was used, only a single LF is sent to the printer. Also, note
that unlike the -wpp option, there is no runtime way to specify
the -wplf option.)

b. If the character to be output is a form feed character,
PROGRESS first checks whether or not PASSTHROUGH mode has been
indicated. If so, and if a POSTSCRIPT printer is also indicated,
then PROGRESS simply does nothing. To do otherwise would serve
no purpose, since presence of PASSTHROUGH mode indicates that the
4GL is sending all pert.inent data. If PASSTHROUGH is indicated
but *not* POSTSCRIPT, then a two-character sequence is sent
directly to the printer: form feed, 0.

If PASSTHROUGH mode is *not* indicated, then the normal Windows
printer handling commands are used to end the current page and
begin a new one.

c. PROGRESS now performs some housekeeping on the current
printer row and column. The column is invariably reset to 0. The
row is set according to whether OUTPUT TO PRINTER or OUTPUT TO LPTn
was specified. For OUTPUT TO PRINTER, row is set to 0. For OUTPUT
TO LPTn, row is set to 1-1/2 lines, just as in the initialization
phase.

d. If the character to be printed is any other character besides
the ones discussed above, PROGRESS checks for PASSTHROUGH mode. If
PASSTHROUGH mode is indicated, the character is sent directly to
the printer. If not in PASSTHROUGH mode, the character is written
to the printer context using the usual Windows APIs, and the
current column is incremented to reflect the new location on the
line.


* Outputting a STRING

PROGRESS normally outputs data in strings. One way of causing
the 4GL to output a string of data is to execute a 4GL statement
such as the following, with output redirected:

DISPLAY name.

Another way is to use the PUT statement with output redirected.

When PROGRESS wants to output a string to a printer, the following
steps occur:

a. PROGRESS checks whether any data exists in the string. A
string of length 0 is ignored.

b. If a DISPLAY or PUT statement is being used, but *not* a PUT
CONTROL statement, then PROGRESS checks for PASSTHROUGH mode. If
PASSTHROUGH is *not* indicated, PROGRESS checks whether the first
first character is ESCAPE (033 octal, 1B hex). If there is an
ESCAPE character in the first position *and* nothing has been
printed yet, PROGRESS automatically switches into PASSTHROUGH mode.
(This is another way to get -wpp printing at runtime without having
to use the startup parameter.)

If there is an ESCAPE character and other text has already been
printed, a warning message is generated. This is because
Windows can behave unpredictably when a print process switches
into PASSTHROUGH mode mid-stream.

For example:

PUT "~033SDFS" DISPLAY "title".
DISPLAY name. PUT "~033[asfasf"
DISPLAY name.
(1) (2)


In (1), PROGRESS will automatically switch into PASSTHROUGH
mode because the ESCAPE character is the first one seen by the
PROGRESS printer output code. In (2), a warning message is
given because the 4GL has already displayed "title" and is
therefore mixing normal text output mode with PASSTHROUGH mode.

The warning message is displayed only once for the duration of
the output. The 4GL statement OUTPUT CLOSE will reset the
internal flag the suppresses the warning once it has been
displayed.

If a PUT CONTROL statement is being used, *and* we are not already
in PASSTHROUGH mode, PROGRESS checks to see if any text has been
output yet. If no text has yet been printed, then PROGRESS goes
into PASSTHROUGH mode. If some text *has* been printed, then the
warning message is displayed and PASSTHROUGH mode is not enabled.

For example:

PUT CONTROL "stuff ~033[asfasf"
DISPLAY name address state.


Here, even though the ESCAPE character is not the first character
in the string, PROGRESS goes into PASSTHROUGH mode automatically
because of the PUT CONTROL statement.

c. Finally, once PROGRESS has determined in which mode to print
the string, another check for PASSTHROUGH takes place. It
PASSTHROUGH is indicated, PROGRESS prints the string directly to
the printer. Otherwise, the normal W.indows printing APIs are used
and PROGRESS updates the current column based upon the number of
characters that were given in the string.


* Outputting a NULL

Some printers require that NULL characters be sent to them as part
of normal operation. This is accomplished in the 4GL by using the
PUT CONTROL NULL or PUT CONTROL NULL(nn) statement. When the
PROGRESS printer code detects a PUT CONTROL NULL, it goes through
the same sequence as for a normal PUT CONTROL - it checks to see
if anything has already been printed without using PASSTHROUGH mode
and displays a warning message if that is the case. Otherwise,
PROGRESS will automatically switch to PASSTHROUGH mode and send the
NULL character(s) directly to the printer.


Closing the Printer

Finally, all printing is complete. PROGRESS encounters the OUTPUT
CLOSE statement.

PROGRESS first determines how to notify Windows that the print job has
ended. If POSTSCRIPT *and* PASSTHROUGH mode are both indicated (by
way of the -wpp startup option or by using PAGE-SIZE 0), we simply
notify Windows that we are finished printing this document.

If neither PASSTHROUGH nor POSTSCRIPT modes are indicated, then
PROGRESS checks to see if an ending form feed is needed and generates
one if necessary. PROGRESS then informs Windows that this document
has finished printing. There follows a general cleanup of fonts
and printer contexts that were used, as well as resetting of internal
flags and freeing up of memory..