May 92 - POSTSCRIPT ENHANCEMENTS FOR THE LASERWRITER FONT UTILITY
POSTSCRIPT ENHANCEMENTS FOR THE LASERWRITER FONT
UTILITY
BRYAN K. ("BEAKER") RESSLER
For System 7, the LaserWriter Font Utility was given the ability to handle drop-in
enhancements, called UTILs. These hybrid Macintosh-and-PostScript utilities are
provided with a rich parameter block and many useful callbacks. They offer a
straightforward method for putting useful tidbits of PostScript code to work--with a
real user interface.
The LaserWriter Font Utility is an obscure system software application that isn't even
installed by the System 7 Installer. Its main mission is to facilitate the downloading of
TrueType, PostScript Type 1, and PostScript Type 3 fonts to PostScript (and
PostScript-compatible) printers and printer hard disks. With System 7, however,
the innocuous LaserWriter Font Utility has been endowed with an extensible Utilities
menu and the ability to handle drop-in enhancements, calledUTILs. UTILs can be used
for a variety of interesting applications. For example:
• downloading a PostScript language file or restarting a PostScript printer
with special-purpose PostScript utilities
• setting the resolution or printing an alignment page on a particular model
of typesetter with device-specific applications
• putting little snippets of PostScript code to work
INTRODUCING UTILS
UTILs are resources that are stored in the LaserWriter Font Utility's application
resource file. When the Font Utility is run, UTILs are collected into the Utilities
menu, listed by their resource name.
UTILs are generally modal and very task-specific. For example, one of the UTILs that
are distributed as part of the Font Utility, Start Page Options, allows users of
PostScript printers to decide whether or not the printer produces a "start page" when
turned on. When the user chooses this UTIL from the menu, the dialog box shown in
Figure 1 appears.
Figure 1 Example of a UTIL Dialog Box
A UTIL performs its task via PostScript code embedded in the UTIL or in its owned
resources. Therefore, UTILs are provided with routines that ease two-way
communication with the PostScript printer.
UTILs may own resources and allocate a block of private "global" memory. UTILs get
printer configuration information from the Font Utility and may also query the
printer directly for configuration information. This allows for device-specific UTILs.
Since most UTILs are expected to be implemented similarly, many application
facilities are provided to UTILs so that common code, like the bold outline for the
default button in Figure 1, is not duplicated in every UTIL. As a result, most UTILs are
very small (under 2K).
UTIL RESOURCES
UTILs are stored as resources of type 'UTIL'. Their IDs start at 128. However, the
range 128 through 149 is reserved by Apple, so you should use an ID of 150 or higher
for the UTILs you write. The UTIL's resource name defines the text of the menu item
that's appended to the Utilities menu.
The UTIL resource format is shown in Figure 2.
The first two bytes of the resource specify the version of the UTIL resource format,
which is currently $0001. Next comes resSpace, the first ID in the UTIL's resource
space. A UTIL'sresource space is the range of IDs that the UTIL may use for its owned
resources. The UTIL has 100 consecutive IDs, starting with resSpace. In general, to
calculate a given UTIL's resource space ID, use the formula
resSpace = 16000 + (UTILID - 128)* 100
where UTILID is the resource ID of the UTIL resource itself. For example, if your UTIL
resource were numbered 158, your UTIL's resource space would be calculated as
follows:
resSpace = 16000 + (158 -128)* 100 = 19000
Figure 2 UTIL Resource Format
In your UTIL's code, it's important to userelative resource IDs, in case your UTIL is
renumbered at installation time. There are several examples of relative resource IDs
in the code we'll be examining.
Following the version and resSpace, the UTIL resource contains offsets to the four UTIL
entry points (described in the next section). These offsets are from the beginning of
the UTIL resource. The beginning and order of entry points is flexible (see
"Variations on UTIL Entry Points" for details).
UTIL ENTRY POINTS
Let's take a quick look at the four UTIL entry points. Later, in the section "The Script:
NamerUTIL.c Code," we go into more detail.
Utility_Open. This routine is called by the Font Utility at startup, right after the
UTIL is loaded into memory. Utility_Open initializes the UTIL and allocates any
memory it requires. Utility_Open needs to return a Boolean result which, if true,
tells the Font Utility to install the UTIL in the Utilities menu. A false result from
Utility_Open, which might occur if there were insufficient memory, tells the Font
Utility not to install this UTIL.
VARIATIONS ON UTIL ENTRY POINTS
There's no requirement that the Utility_Open routine start at offset 20, nor is there
any specification of the order in which the routines are stored within the resource.
This allows noncode data to be stored in the UTIL resource along with the code. Figure 3
shows an example of PostScript code stored inside a UTIL resource, and the four
routines rearranged as desired.
While this method of storage works well for embedded PostScript code, remember that
other textual data (that's not PostScript code) should be stored in resources to
facilitate localization.
Figure 3 Arranging UTIL Routines
Utility_Delta. This routine is called by the Font Utility once after Utility_Open and
subsequently any time the user selects a different printer with the Chooser.
Utility_Delta is the means by which a UTIL informs the Font Utility whether the
UTIL's menu item should be dimmed or not (usually based on the characteristics of the
currently selected printer). The Font Utility provides a host of useful printer
configuration information, but should your UTIL require different or more specific
information, it may download PostScript code at this point and parse the response from
the printer. Utility_Delta needs to return true if the UTIL's menu item is to be
available, or false if it's to be dimmed.
Utility_Prime. This routine is called by the Font Utility to carry out the basic
function of the UTIL. It's called when the user chooses your UTIL's menu item from
the Utilities menu. The Start Page Options UTIL described earlier downloads some
PostScript code to determine the current state of thedostartpageflag in the printer,
puts up a dialog box, and then downloads more PostScript code to set the flag to the new
setting. The Utility_Prime routine needs to return a long word composed of (possibly
multiple) return codes. These codes tell the Font Utility of any special behavior it
should take upon return, such as refreshing its font lists.
Utility_Close. This routine is called by the Font Utility at quit time. Normally, at
this point your UTIL releases any memory it has allocated.
GOODIES IN THE LWFUPARMBLK STRUCTURE
When the LaserWriter Font Utility is starting up, it allocates one LWFUParmBlk for
each installed UTIL. That means that each UTIL's parameter block is unique, and the
same block is always passed to it. Each of the entry points described above takes as a
parameter a pointer to an LWFUParmBlk structure. This structure is discussed in
detail in the section "The Script: NamerUTIL.c Code," but here are the high points.
General information. This part of the structure includes the version of the
LWFUParmBlk structure, the base resource ID for this UTIL's resource space, and a
storage field into which the UTIL may place a handle to some global storage space.
Driver information. You're provided with an FSSpec pointing to the currently
selected printer driver. Tempting as this might be, you should use this only to
retrieve the driver's version, allowing your UTIL to put the driver version in a dialog
box.
Printer information. This includes the name of the current printer and a host of
printer configuration information. Also included is a handle to the Font Utility's own
standard Macintosh print record, which allows you to print via the Printing Manager
if you wish.
Callback information. This is a rich set of callbacks into the Font Utility. There's
also a pointer to the Font Utility's QuickDraw globals and pointers to two large I/O
buffers you can use for printer communication. The callback routines can be grouped
into three major categories:
• 3 PAP routines that assist in printer communication
• 18 dialog utility routines, many of which you would have probably had to
include anyway
• 4 Pascal-string utility routines that aid in the construction of PostScript
language strings
ON STAGE: NAMERUTIL
Now that we've got an overview of how UTILs fit into the LaserWriter Font Utility,
let's take a closer look at a specific example, NamerUTIL, provided on theDeveloper CD
Series disc. NamerUTIL, which appears in the Utilities menu as Rename Printer,
allows the user to rename the currently selected printer.
Figure 4 shows part of the Utilities menu, including the Rename Printer UTIL.
Figure 4 UTILs in the Utilities Menu
Rename Printer's Utility_Prime routine presents the user with the dialog box shown
at the top of Figure 5. The dialog is smart enough to limit the length of the new name to
30 characters and disallow various illegal characters. If the user clicks Rename, the
UTIL transmits a PostScript program to rename the printer as specified. The UTIL
then puts up one of the two alerts shown in Figure 5, depending on whether the printer
was successfully renamed or not.