® Tips for Working with the New PostScript Printer ®®Driver for Adobe Developer Support

Technical Note #5134

2 April 1993

Adobe Systems Incorporated

Adobe Developer Technologies 345 Park Avenue San Jose, CA 95110 http://partners.adobe.com/

PN LPS5134

Copyright  1993 by Adobe Systems Incorporated. All rights reserved.

No part of this publication may be reproduced, stored in a retrieval system, or transmitted, in any form or by any means, electronic, mechanical, photocopying, recording, or otherwise, without the prior written consent of the publisher. Any software referred to herein is furnished under license and may only be used or copied in accordance with the terms of such license.

PostScript is a registered trademark of Adobe Systems Incorporated. All instances of the name PostScript in the text are references to the PostScript language as defined by Adobe Systems Incorpo- rated unless otherwise stated. The name PostScript also is used as a product trademark for Adobe Sys- tems’ implementation of the PostScript language interpreter.

Any references to a “PostScript printer,” a “PostScript file,” or a “PostScript driver” refer to printers, files, and driver programs (respectively) which are written in or support the PostScript language. The sentences in this book that use “PostScript language” as an adjective phrase are so constructed to rein- force that the name refers to the standard language definition as set forth by Adobe Systems Incorpo- rated.

Adobe, PostScript, the PostScript logo, and Display PostScript are trademarks of Adobe Systems Incorporated which may be registered in certain jurisdictions. Apple, AppleTalk, LaserWriter, Mac, and Macintosh are registered trademarks and QuickDraw is a trademark of Apple Computer, Inc.

This publication and the information herein is furnished AS IS, is subject to change without notice, and should not be construed as a commitment by Adobe Systems Incorporated. Adobe Systems Incorpo- rated assumes no responsibility or liability for any errors or inaccuracies, makes no warranty of any kind (express, implied or statutory) with respect to this publication, and expressly disclaims any and all warranties of merchantability, fitness for particular purposes and noninfringement of third party rights.

Contents

Tips for Working with the New PostScript Printer Driver for Macintosh 5 1 Introduction 5 Who Should Read This Document 5 2New Driver Overview 6 3Driver Architecture 8 2 Pass design 8 The md Dictionary 9 PostScript Interpreter Graphics State Management 9 Page Setup and Print Dialogs 10 4 Compatibility Issues 11 Determining the Identity of the Driver 12 Use of LaserPrep procedures 12 Flushing the QuickDraw Graphics State into a QuickDraw Picture 13 PostScript Language PicComments 14 Emitting Device Setup Code 17 EPS File Generation and Import 18 Emitting Binary Data 21 5New PrGeneral Calls 22 Obtaining the PPD File for the Target Printer 23 Obtaining Information about the Target Printer 24 6 References 28 General References 28 PostScript Language References 29

Index 31

iii

iv Contents (2 Apr 93)

Tips for Working with the New PostScript Printer Driver for Macintosh

1 Introduction

Adobe Systems Incorporated and Apple Computer have jointly developed a new PostScript™ printer driver for Macintosh®. This driver, referred to here as PSPrinter, is a replacement for the existing Apple® LaserWriter® driver. PSPrinter is not a modified LaserWriter driver but is a complete rewrite. The architecture and code generation strategy of PSPrinter is significantly differ- ent than the existing LaserWriter driver and allows for the generated Post- Script language code to be more efficient and to conform to conventions for structured PostScript language code.

This technical note is intended to alert application writers to the differences between the PSPrinter driver and the existing Apple LaserWriter driver (referred to here as the ‘old LaserWriter driver’, meaning all LaserWriter drivers prior to version 8.0) from the viewpoint of application writers. It highlights areas where compatibility issues exist and how developers can avoid compatibility problems. Most of the compatibility problems are due to techniques, used by application developers, which have long been discour- aged by Apple. Other areas are more subtle, and application writers may not be aware of their dependencies on the old Apple LaserWriter driver architec- ture.

1.1 Who Should Read This Document

Most of this document is intended to aid application developers who generate their own custom PostScript language code via one of several mechanisms available to Macintosh applications. Typically these are the application devel- opers who either knowingly or unknowingly take advantage of the structure and operation of the old LaserWriter driver. This document tries to address some of the architectural differences between PSPrinter and the old Laser- Writer driver and how these differences may impact the PostScript language code an application emits.

Section 2 discusses some of the design objectives of the new driver. Section 3 gives a brief overview of the architecture of the driver, laying the groundwork for discussion of areas where application writers might encounter differences

5

between PSPrinter and the old LaserWriter driver. Section 4 goes into depth on specific compatibility issues which have been identified and discusses ideas for avoiding these compatibility problems. Section 5 discusses new PrGeneral selectors and how they may be used to allow applications to gather more information about the current print job and target printer. Finally section 6 gives a list of references which may be useful to Macintosh applica- tion writers, both those who generate custom PostScript language code during printing and those who allow the driver to generate all the PostScript language code.

Application writers who allow the driver to generate all the PostScript lan- guage code during the printing process should read the following:

•section 3.4 discussing the page setup and print dialogs

•section 4.6 discussing EPS file generation

• the relevant documents listed in section 6 which discuss aspects of print- ing and print driver compatibility which are not necessarily specific to printing through PSPrinter or the old LaserWriter driver.

Writers of applications who generate any custom PostScript language code while printing with the old LaserWriter driver are encouraged to carefully read this complete document, especially section 4.

2New Driver Overview

The new driver completely replaces the old LaserWriter driver.

The principal design goals of the new driver were:

•To make full use of the new capabilities available in PostScript Level 2 software (such as data compression, improved pattern rendering, rectangle drawing primitives, and device-independent color calibration) while main- taining compatibility with older, Level 1 output devices

•To improve performance when printing to all PostScript printers

•To provide user access to all device-specific features of any chosen output device through a dynamically extensible user interface

•To allow for future expansion and adaptation through a modular architec- ture for network communications

•To improve flexibility and compatibility by allowing PostScript language files to be saved in a variety of portable formats, including Encapsulated PostScript language file format (EPS).

6 Tips for Working with the New PostScript Printer Driver for Macintosh (2 Apr 93)

•To generate output files conforming to Adobe’s document structuring con- ventions (DSC).

While some of the improvements available with PSPrinter may not be obvi- ous at the user interface level of the driver, such as improved performance and PostScript Level 2 software support, there are several improvements which provide new functionality to end users. The ability to handle 2-up and 4-up printing (see Figure 1) is a direct result of PSPrinter’s generation of con- forming PostScript language code. The ability to allow for extended paper sizes and paper bin support (see Figure 2) is due to the driver’s use of Post- Script Printer Description (PPD) files for configuring the user interface and generating device specific code. The ability to generate EPS files (see Figure 3) is available, again because of PSPrinter’s generation of conforming Post- Script language code.

Figure 1 Page Setup Dialog

Figure 2 Print Dialog

2 New Driver Overview 7

Figure 3 Print to Disk Dialog

3 Driver Architecture

This section includes a short summary of the PSPrinter architecture. This dis- cussion describes the way the new driver functions. This is necessary in order to discuss the application compatibility issues described in section 4.

3.1 2 Pass design

PSPrinter is by design a 2-pass driver. In order to optimize the generated PostScript language code, it first spools the application drawing to disk as a sequence of QuickDraw™ pictures, one for each page. When the application calls PrCloseDoc the driver completes writing the spool file to disk. The set- ting of foreground printing or background printing controls when the second pass is completed. If Background printing is Off, then the application’s call to PrCloseDoc causes PSPrinter to perform the second pass of printing before PrCloseDoc returns. PSPrinter opens the connection to the printer, performs queries for fonts and other information, calls DrawPicture on each picture in the spool file, and converts the resulting QuickDraw calls to PostScript lan- guage code. When all the pages have been sent to the printer, PSPrinter closes the spool file and PrCloseDoc returns. At that point, the user regains control.

8 Tips for Working with the New PostScript Printer Driver for Macintosh (2 Apr 93)

If Background printing is On, PrCloseDoc returns control to the application. The second pass is handled by PrintMonitor as it is with the old LaserWriter driver: the connection to the printer takes place and the PostScript language output is generated. In order to maintain compatibility with the old Laser- Writer driver, PSPrinter still reports itself to be a draft printer driver even though it behaves more like a spooling driver regardless of whether back- ground printing is On or Off.

3.2 The md Dictionary

The PostScript language code generated by PSPrinter is completely different than that of the old LaserWriter driver. PSPrinter continues to use the dictio- nary ‘md’ for storing its privately defined procedures. The procedures used and their names are typically completely different from those used by the old LaserWriter driver. In a few cases there is a procedure named as in the old LaserWriter driver; however, this is done rarely and only when the function- ality is identical.

PSPrinter does not maintain its dictionary outside the PostScript printer server loop as pre-7.0 LaserWriter writers did. By containing the driver prolog code completely within the PostScript language job currently being printed, each job is self contained and does not conflict with other users on the network. PSPrinter is simultaneously compatible with users of older LaserWriter drivers printing to the same printer.

In order to reduce the amount of PostScript language code sent for each print job, during its first pass PSPrinter analyzes the contents of the application generated QuickDraw code and includes only the portions of its PostScript language prolog code necessary to draw the associated pages. This allows PSPrinter to cut down on the size of the header included in each job.

3.3 PostScript Interpreter Graphics State Management

PSPrinter maintains its view of the state of the PostScript interpreter on the host as it generates the necessary PostScript language code to match that of the QuickDraw graphics state. PSPrinter generates the code necessary to match the color, pen size, clip, coordinate system orientation and so forth as QuickDraw graphics are converted to PostScript language code. This general approach is no different than the old LaserWriter; however, the PostScript language code used to maintain the state of the PostScript interpreter is dif- ferent in some cases.

PSPrinter manages the clipping path in the PostScript interpreter through the use of the PostScript language operators gsave and grestore. Before chang- ing the clipping path in the PostScript interpreter, PSPrinter issues a gsave in order to save the old clip. If the clipping rectangle changes to a new clip which is not completely inset in the old clipping rectangle, then a grestore is

3 Driver Architecture 9

issued to obtain the original saved clip. Before changing the clip, PSPrinter then issues a gsave to save the original clip again. By nesting clipping changes inside of gsave/grestore pairs, PSPrinter avoids execution of init- clip and therefore generates conforming PostScript language code.

PSPrinter similarly handles changes to the orientation of the PostScript lan- guage coordinate system generated by the object rotation picture comments (see Macintosh Technical Note Picture Comments–The Real Deal (old #91)) and text scaling, flipping, or rotation. When a text or object rotation begins, PSPrinter issues a gsave to save the old orientation before scaling or rotating the coordinate system. Once the new coordinate system is no longer needed, a grestore is executed to reinstate the saved coordinate system.

When PSPrinter executes a grestore to manage the graphics state, the state of the PostScript language graphics state (color, line width, scale, orientation, origin and so forth) reverts to that saved with the last gsave. PSPrinter keeps track of the saved graphics state on the host and when a grestore is executed by PSPrinter on the printer, it uses its saved copy on the host to determine what parameters must be set in the PostScript interpreter in order to correctly draw the QuickDraw graphics object. PSPrinter sends the necessary code to set the PostScript language graphics state correctly, then draws the object.

PSPrinter encloses each page generated by an application inside a save/ restore pair. This isolates each page from any state which is modified on a previous page and isolates subsequent pages from the state changes of the current page. In order to conform to the document structuring conventions, the showpage necessary to print a given page is emitted after the page level restore. This properly isolates each page from previous pages and also allows a redefinition of showpage to handle n-up printing and other post- processing features available to DSC-conforming documents.

3.4 Page Setup and Print Dialogs

As is apparent in Figures 1 and 2, PSPrinter has a substantially new dialog layout for both the Page Setup dialog and Print dialog. Both these dialogs now have an options dialog associated with them. Because of the additional functionality available in these dialogs, the dialog item numbers are different than the old LaserWriter driver.

The content of many of the driver dialogs depends on the features of the cur- rently chosen printer and hence the currently chosen PostScript Printer Description (PPD) file. The user associates a PPD file with a given printer in the Chooser. By default, the PPD file associated with each printer is a generic PPD file built into the driver. This generic PPD file provides the paper image- able areas and printer features equivalent to those in the old LaserWriter driver. The user may choose a different PPD file by using the Setup button in

10 Tips for Working with the New PostScript Printer Driver for Macintosh (2 Apr 93)

the Chooser and either automatically or manually set up the printer. Once a PPD file is associated with a printer, PSPrinter remembers this in its prefer- ences file so when that printer is chosen again, the correct PPD file is auto- matically used.

In order to use a given PPD file, PSPrinter must first parse the contents of the file and build the data structures necessary for driving the user interface. Because of memory limitations in many applications, the PPD file is parsed in the Chooser. When the user selects a new printer in the Chooser, PSPrinter parses the PPD file associated with that printer and writes the parsed data to the data fork of the preferences file. Selecting a different printer in the Chooser causes PSPrinter to parse the PPD file for the new printer (if the PPD file is a different file than the previous printer’s PPD file) and overwrite the contents of the preferences file data fork.

When an application calls PrStlDialog, the pre-parsed contents of the of PPD file residing in the data fork of the preferences file are used to build the con- tents of the Page Setup dialog. For example, the list of paper sizes (and the corresponding rPaper and rPage rectangles) are built based on the contents of the PPD file for the last printer chosen in the Chooser (called here the target printer). When an application calls PrJobDialog the pre-parsed contents of the PPD file are used to fill in the input bin list, indicate the ability to handle PostScript fax, and fill in the contents of the Print Options dialog if necessary.

4 Compatibility Issues

Many applications generate only QuickDraw drawing and do not generate any custom PostScript language code. These applications are the least likely to suffer compatibility problems with any new PostScript printer driver. The problems these applications encounter are general compatibility problems such as reliance upon specific dialog items or strange assumptions about the print record. Apple has clearly specified many areas of ‘print crimes’ which are likely to cause application incompatibility with new drivers. See section 6 for a summary of documents which discuss such print crimes.

Applications which are more likely to suffer compatibility problems with PSPrinter are those applications which generate their own custom PostScript language code. Most of the problems such applications may encounter are described here. While this is not an exhaustive list of problems, these are some areas to examine in your application to ensure there are no problems.

Note that many of the differences between the old LaserWriter driver and PSPrinter also apply to the printing architecture under QuickDraw GX. Many of the compatibility issues which are present with PSPrinter as compared to the old LaserWriter driver are also present with the QuickDraw GX Post- Script printer driver as compared to the old LaserWriter driver.

4 Compatibility Issues 11

4.1 Determining the Identity of the Driver

PSPrinter and the old LaserWriter driver are intended to look identical to applications. In particular the wdev field of the print record is the same so that applications identify PSPrinter as a PostScript printer driver. In some cases it may be useful to detect that PSPrinter is the current driver, not the old LaserWriter driver. This may be done by checking the result of the Macintosh Toolbox function PrDrvrVers(). The old LaserWriter driver version is always less than 80, while the PSPrinter version is greater than or equal to 80 and less than 100.

Note: The name of the driver should never be used as an indication as to whether it is the old LaserWriter driver, PSPrinter, or some other printer driver. Indeed, PSPrinter is shipped by different Adobe customers under a number of different names.

4.2 Use of LaserPrep procedures

PSPrinter does not use the same PostScript language procedures as the old LaserWriter driver when generating its PostScript language code. In other words, it does not use ‘LaserPrep’. Apple has long considered reliance on LaserPrep procedures to be a ‘print crime’. In order to maintain compatibility with PSPrinter, applications should not emit code which uses LaserPrep defined procedures. Such code will generally result in a PostScript language undefined error and the job will not print properly. In order to eliminate such problems, an application must define the procedures it requires instead of assuming they are available from the existing printer driver. Note that it is an equally serious print crime to assume the existence of any new procedure defined by PSPrinter. These procedures are private and may change without notice. Reliance on such procedures severely limits the ability to revise the drivers to allow improved performance and new features.

Some applications define names which they expect will be used by the driver during its execution. Typically these names are re-definitions of procedures which are used by the old LaserWriter driver. PSPrinter does not use the same procedures and names as the old LaserWriter driver so such re-defini- tions will not cause any execution of the application defined underlying code. Generally speaking this will not result in PostScript language errors but will still result in incorrect output.

PSPrinter does name its private dictionary md in order to improve compati- bility with existing applications which assume its existence. It is still impor- tant to not rely on the contents of the md dictionary.

12 Tips for Working with the New PostScript Printer Driver for Macintosh (2 Apr 93)

4.3 Flushing the QuickDraw Graphics State into a QuickDraw Picture

One feature of QuickDraw which surprises many application writers is how it creates QuickDraw pictures. Instead of recording all calls to change the QuickDraw grafport state, QuickDraw instead records changes from the pre- vious state when it actually draws a new graphic element. By doing this, any extraneous calls to change the state of the grafport are ignored, only those changes necessary to draw the next graphic are recorded into the QuickDraw picture. For example, if the previous object were framed with a pen size of 2,2 and the pen were changed first to 3,3 and text was drawn using DrawText, then the pen was set back to 2,2 before a new QuickDraw rectangle was framed, the picture would contain no recording of the pen width changes since they did not affect any drawn graphics.

This mechanism works very well except that the QuickDraw picture creation mechanism does not consider calls to StdComment to be QuickDraw draw- ing operations. Because of this, changes to the grafport made after drawing the last QuickDraw graphic but before use of a picture comment are not recorded in the QuickDraw picture. This affects generators of custom Post- Script language code through the use of the PostScriptBegin picture comment (see section 4.4 for more information on PostScriptBegin).

Why the Initial Clip for PostScript Language Code May be Zero

One example of how this problem may surprise developers is that the initial clip in a QuickDraw picture before any QuickDraw drawing is performed is a rectangle of zero width and height. If the first “drawing” done by the creator of the picture is done by custom PostScript language code emitted by picture comments then the clip in effect at that time is the zero clip. The result is that any drawing done by the custom PostScript language code emitted before any QuickDraw drawing will be clipped out. Once an application actually draws a line, rectangle, text, copybits, etc. then the clip in the grafport is set correctly by the picture drawing mechanism. The simple work around for application writers which generate PostScript language code before any QuickDraw code is to first draw either a zero width line or a space character in a font you require for your PostScript language code. This will cause QuickDraw to properly set the clip in the QuickDraw picture before your custom PostScript language code is executed.

As described above, another problem frequently appearing is that a change your application made to the grafport does not appear before your PostScript language code is executed. The solution is to ensure that the proper Quick- Draw state is flushed into the QuickDraw picture by first drawing an appro- priate object before calling PostScriptBegin. For ensuring the pen color and initial clip to the picture, set the appropriate grafport entries, then draw a zero width line of zero length. This flushes the changes to the QuickDraw state into the grafport. If a specific font is required for your custom PostScript lan-

4 Compatibility Issues 13

guage drawing, first set the font in the grafport, then draw a space character in an arbitrary location. If the previous pen position is also important for your custom PostScript language code, then draw a zero width line of zero length at the pen location required. See Example 1 for an example of this code. Macintosh Technical Note Picture Comments–The Real Deal (old #91)) con- tains a procedure FlushPortState which provides similar functionality.

Example 1: Flushing the QuickDraw State

void FlushQDState() { PenState penInfo; GetPenState(&penInfo); PenSize(0,0); Line(0,0); SetPenState(&penInfo); }

4.4 PostScript Language PicComments

Applications insert PostScript language code into the print stream with the use of the QuickDraw picture comments PostScriptBegin, PostScriptHandle, TextIsPostScript, PostScriptEnd, and PostScriptBeginNoSave. Typically these comments are used as follows

PicComment(PostScriptBegin,0,0); PicComment(PostScriptHandle,GetHandleSize(h),h); …numerous uses of PostScriptHandle… PicComment(PostScriptEnd,0,0);

The handle h contains the PostScript language code to be inserted into the print stream. The coordinate system in effect at the time of execution of the PostScript language code in the handle is the same as the QuickDraw coordi- nate system: the origin of coordinates is at the top left corner of the imagea- ble area of the page with the y coordinate increasing down the page.

Normally PSPrinter (and the old LaserWriter driver) encloses the code exe- cuted within a PostScriptBegin/End sequence in a save/restore pair. This limits the effects of changes to the PostScript language graphics state and VM to the execution of the code contained within the PostScriptBegin/End sequence. Once PostScriptEnd is executed, the graphics state is restored to that in effect at the time PostScriptBegin was executed. This prevents the PostScript language code executed by an application from interfering with the driver’s generated code.

Some applications use the picture comment PostScriptBeginNoSave in order to emit PostScript language code without the enclosing driver save/ restore. This allows the application to change the state of the PostScript interpreter in a way that persists beyond the execution of the application gen-

14 Tips for Working with the New PostScript Printer Driver for Macintosh (2 Apr 93) erated PostScript language code. Unfortunately the use of this picture com- ment allows an application to interfere with the driver and cause it to execute under circumstances beyond its control. Additionally, changes to the graphics state intentionally done by an application may be undone by a driver gener- ated grestore. One example when this can happen is when the driver must change the clipping rectangle. If your application uses PostScriptBegin- NoSave you should carefully examine the results you obtain with PSPrinter. Use of this construct can lead to incorrect clipping, incorrect colors, and pos- sibly PostScript language errors. It is strongly recommended that the Post- ScriptBeginNoSave PicComment be avoided.

An example of an application’s use of PostScriptBeginNoSave is an applica- tion which sets the PostScript language drawing color for an object which is to be drawn by QuickDraw. Some applications do this to allow color drawing on a machine which does not have Color QuickDraw or to allow specification of colors in a manner not allowed by QuickDraw (such as a CMYK color model).

This can cause two different problems. When drawing with calibrated color, PSPrinter relies on the color space in the printer being set to its own special color space (a PostScript Level 2 software feature). Execution of setgray, setrgbcolor, and setcmykcolor changes the color space from this special color space. Use of these operators inside of PostScriptBegin/End works quite well. However, if an application emits this PostScript language code outside of the driver save/restore it changes the PostScript language color- space currently in effect during the execution of the driver generated Post- Script language code. This will likely cause PostScript language errors during printing. Applications which emit such code outside the driver save/ restore will most likely not be able to print using the Calibrated Color fea- ture available in the print options dialog.

A second problem which occurs is a synchronization problem between the application’s PostScript language code and the driver’s maintenance of the clip in the graphics state. If an application generates PostScript language code to set the color after the last driver gsave, then a grestore emitted by the driver will undo the change to the color set by the application’s custom PostScript language code. Examples 2 and 3 illustrate how the driver’s main- tenance of the clip can interfere with an application’s efforts to set the draw- ing color. Example 2 is C code illustrating what some applications now do in order to do their own coloring of QuickDraw objects. Example 3 is pseudo output from PSPrinter and indicates why the C code does not accomplish the desired result.

4 Compatibility Issues 15 Example 2: Use of PostScriptBeginNoSave to Set the Color

Handle h; char *mystring; short err; Rect r;

SetRect(&r,20,20,120,120); ClipRect(r); // set the clip before drawing FlushQDState(); // as defined above mystring=(char *)"\p .3 setgray\r"; // change the color err = PtrToHand(mystring+1, &h, mystring[0]); PicComment (PostScriptBeginNoSave,0,0); PicComment (PostScriptHandle, GetHandleSize(h), h); PicComment (PostScriptEnd,0,0);

PaintRect(r);

SetRect(&r,120,120,220,220); ClipRect(r); // set the clip before drawing // assume the drawing color is .3 setgray PaintRect(r);

Example 3: PostScript Language Code Generated for Example 2

gsave % PSPrinter saves the old clip 20 20 100 100 rectclip % then sets the new clip rectangle .3 setgray % Application PicComment 20 20 100 100 rectfill % PSPrinter fills the rect

% now clip is changing grestore % restore old larger clip in preparation % for new clip % note that this grestore sets the color % back to that when the gsave was done

% since PSPrinter didn’t know the color changed, it % won’t set it back to .3 setgray but assumes it is % correctly set to the last color it knew about gsave % PSPrinter saves the old clip again 120 120 100 100 rectclip % set the new clip 120 120 100 100 rectfill % fill the new rectangle

Note: Both PSPrinter and the Apple LaserWriter driver implement Post- ScriptBegin and PostScriptEnd with a pair of driver-defined PostScript lan- guage procedures, psb and pse, which in turn invoke the save and restore operators. Some client programs use these procedures to achieve the same effect as the PostScriptBeginNoSave comment: by issuing a call to pse to restore the PostScript interpreter state just after PostScriptBegin and one to psb to save the state just before PostScriptEnd, they effectively isolate their custom PostScript language code outside the range of any save and restore. This practice can lead to the same kinds of problem described above for PostScriptBeginNoSave.

16 Tips for Working with the New PostScript Printer Driver for Macintosh (2 Apr 93) Note: Applications which generate their own document structuring conven- tions (DSC) comments as part of their custom PostScript language code should be careful to ensure that the resulting output stream is DSC compli- ant. A frequent mistake is to generate DSC comments which should not nor- mally appear on a given document page unless the code is enclosed by %%BeginDocument/%%EndDocument. Some post-processing utilities (such as previewers) cannot handle such non-conforming files. It is up to the gener- ator of the PostScript language comments to ensure that they conform when present in the print stream.

4.5 Emitting Device Setup Code

Some applications allow users to choose from a list of paper sizes which are not available with the old LaserWriter driver. Some applications may also allow users to specify custom paper sizes. Such applications usually emit device setup code (such as the operators letter, tabloid, setpageparams, or setpagedevice) in order to achieve the desired effect.

Note: In many cases the need to generate special device setup code is elimi- nated since PSPrinter now makes available significantly more paper sizes through its use of the PPD files. It may be possible to modify your application dialogs in order to allow the user to select from the standard interface and avoid conflicts between PSPrinter generated code and your application device setup code described here. Note also that generating your own device setup code interferes with a user’s ability to choose different paper output bins for the first and subsequent pages.

It is important to execute application generated device setup operators out- side of the save/restore which encloses a given page. Execution of these operators causes a new device to be installed into the PostScript interpreter graphics state. Installing a new device erases the page. If a new device is installed after the save then a subsequent restore re-installs the device which was saved, thus erasing the page. If the old device is restored immediately before the showpage, as would be the case with PSPrinter, then a blank page will result. Applications which emit device setup operators on a page with the old LaserWriter driver do not get blank pages since the old LaserWriter driver generates showpage before the page level restore. PSPrinter gener- ates restore before showpage in order to conform to the document structur- ing conventions and enable n-up printing.

The solution for such applications is to take advantage of the PREC 103 mechanism. PSPrinter and the old LaserWriter driver both allow an applica- tion to include PostScript language code in the document setup portion of the PostScript language code stream. If a PREC 103 resource is available, that resource is included directly into the output stream as part of the document setup. PSPrinter includes the contents of PREC 103 into the PostScript code output stream after it performs its document level device setup. This allows

4 Compatibility Issues 17 an application to include its own device setup so that it is not undone by device setup done by PSPrinter and to include it into the print stream before any page level saves are done, thus avoiding the blank page problem. To take advantage of this technique an application must add the necessary device setup code to its PREC 103 before starting the print job.

This is typically done by building a PREC 103 resource in memory. If your application already has a PREC 103 resource today then all that is required is to do a GetResource to read that resource into memory, then add the appro- priate device setup code to the end of the resource before calling PrOpen- Doc. Do not call ResourceChanged on this resource so that the copy in your application on disk is not changed. Finally, when done with this current print job, call ReleaseResource to ensure that a call to GetResource by subse- quent print jobs will result in the copy from disk which does not contain spe- cial device setup code. Even if you are not currently using the PREC 103 mechanism, this technique will work if you put an empty PREC 103 resource in your application and treat it as described above.

Unfortunately, the old LaserWriter driver includes the PREC 103 resource before its own device setup, thus it isn’t possible to have the same code work properly with both PSPrinter and the old LaserWriter driver. In this case it is necessary to identify which driver is the current driver during printing (see section 4.1) and proceed accordingly. Existing code will work properly only with the old LaserWriter driver.

Additionally, the use of device specific operators such as letter, set- pageparams, and setpagedevice is not allowed as part of an EPS file. It is strongly recommended that applications generating such code detect when an EPS file is being generated and suppress such device specific code from the output stream under those circumstances. See section 5 about the new PrGeneral selectors which allow an application to detect this situation with PSPrinter.

4.6 EPS File Generation and Import

PSPrinter allows users to generate EPS files from virtually all applications. It allows three different formats of the generated preview image for the EPS file, two forms of PICT preview for Macintosh and an EPS file with no pre- view. This section discusses how to make sure your application allows users to generate the best possible EPS files during printing to disk. This section also discusses tips for applications which allow users to import or place EPS files and print them.

18 Tips for Working with the New PostScript Printer Driver for Macintosh (2 Apr 93) Best EPS Preview Generation

PSPrinter can generate two different types of previews when creating EPS files. In both cases, PSPrinter uses the QuickDraw generated by an applica- tion when printing to create the preview image. The EPS Macintosh Stan- dard Preview is created by drawing the QuickDraw picture spooled by PSPrinter during printing (see section 3.1) into a 72 dpi black and white bit- map. This bitmap is used to create a PICT resource which is then added to the EPS file created on disk. This results in a low resolution black and white pre- view similar to that generated by most applications which currently generate EPS files. PSPrinter creates the EPS Macintosh Extended Preview by taking the QuickDraw picture spooled during printing and turning it directly into the PICT preview resource. The resulting PICT preview is therefore a direct recording of the application generated QuickDraw. For line art and text drawing, this PICT may be of smaller size and higher quality when pre- viewed on screen.

During creation of EPS files, PSPrinter must calculate the bounding box of the graphics being drawn. This is fairly straightforward for most drawing, but when an application emits custom PostScript language code using the Post- ScriptBegin/End construct, PSPrinter has little information about the bound- ing box of the resulting drawing. In this case, PSPrinter uses the current clipping rectangle as the bounding box since it is the upper bound on all drawing by properly conforming PostScript language code generated (since conforming PostScript language code does not generate initmatrix, init- graphics, initclip, or any device setup operations such as those described in section 4.5). Typically applications do not change the clip before generating their custom PostScript language code. If applications set the clip to the bounding box of the graphics represented by the custom PostScript language code, PSPrinter can more accurately estimate the bounding box of custom PostScript language code and compute a more accurate bounding box for its own generated EPS files. In order to ensure that the clip is correctly flushed into the spooled QuickDraw picture it may be necessary to apply the tech- niques described in section 4.3.

Creating the PICT preview before adding it to the EPS file can be somewhat memory intensive. It is best for an application to discard unnecessary data and code before calling PrCloseDoc. By doing so, PSPrinter will have more memory available at the time that it actually creates the preview portion of the EPS file. This is particularly true when the generated PICT preview may be quite large, such as for an image editing application.

There are a number of circumstances where printing from an application may generate previews which are of poor quality or are nonexistent. Most of these problems are due to use of QuickDraw picture comments without generating the appropriate QuickDraw representation. For example, some applications generate only custom PostScript language code when printing to a PostScript printer driver and never the corresponding QuickDraw representation. These

4 Compatibility Issues 19 applications will generate a blank preview. Other applications generate QuickDraw for some objects and only custom PostScript language code for others. These applications will generate only partial previews.

With PSPrinter’s ability to generate EPS files, users will benefit when appli- cation writers emit accurate QuickDraw representations for their custom PostScript language code. Applications should also include an accurate QuickDraw representation for other PicComment features such as rotated text and graphics (see Macintosh Technical Note Picture Comments–The Real Deal (old #91) for more information).

Applications that wish to continue generating the minimum QuickDraw during most printing through PSPrinter but also wish to generate improved EPS preview images may use the PrGeneral call described in section 5 to detect when an EPS preview image will be generated.

Note: Use of the TextIsPostScript picture comment is generally unsuitable when PSPrinter is generating a PICT preview for an EPS file. Applications which use this feature should switch to the PostScriptHandle form of specify- ing custom PostScript language code in order to generate correct screen pre- views.

Placing and Printing EPS Files

Many Macintosh applications allow users to import (or place) EPS files as a graphic element to be added to the current document. These applications usu- ally allow the imported graphic to be scaled, translated, rotated, and skewed. Printing such documents to a PostScript printer requires an application to pass the PostScript language content of the EPS file through the printer driver, typically using the PostScriptBegin/End sequence.

PSPrinter generates EPS files with EPS version number 3.0. This should cause no compatibility problems for well behaved applications. When fonts are used as part of a document, PSPrinter uses both the %%DocumentFonts comment to list all fonts used within the document and the %%Document- SuppliedFonts comment for fonts which are actually supplied in the docu- ment. Applications can determine which fonts must be downloaded in order to obtain correct results by subtracting the %%DocumentSuppliedFonts from the %%DocumentFonts list. Only the fonts remaining after the subtraction must be downloaded by the importing application in order to obtain correct results.

The EPS guidelines specify that applications should use the %%BoundingBox comment as the description of the size and location of the graphic when importing the drawing. The coordinate system in which this data is specified is the default PostScript language coordinate system where the origin is in the lower left corner of the paper with one unit equal to 1/72 of an inch. The %%BoundingBox comment is the correct specification of the bounds and

20 Tips for Working with the New PostScript Printer Driver for Macintosh (2 Apr 93) location of the graphic; the PicFrame of the preview image is not. In some cases, the %%BoundingBox and PicFrame may be different. In all cases, the data in the %%BoundingBox comment is correct.

When emitting the PostScript language code for placing an EPS file, applica- tions typically must generate code surrounding the EPS stream in order to size and locate the EPS graphic in the proper location on the page. The coor- dinate system in effect following the PostScriptBegin PicComment is the QuickDraw coordinate system. The origin of coordinates is the current QuickDraw origin (typically the top left corner of the imageable area of the page but it may be translated because of application SetOrigin calls). The scale of the PostScript language coordinate system after the PostScriptBegin PicComment is that of the application which is printing; typically 72 units per inch but it will be different if a PrGeneral SetRsl call is made. In all cases, the coordinate system has the y axis ascending down the page.

Appendix H of the PostScript Language Reference Manual, Second Edition has a complete discussion of the proper steps for correct inclusion of EPS files into the print stream. The only information required is the origin of the box representing the graphic (in QuickDraw coordinates), the size of the box in the QuickDraw coordinate system, and the data in the %%BoundingBox comment from the EPS file itself.

There is never a need to generate initgraphics or initmatrix when including PostScript language files into the print stream. There is no need to know whether the page is landscape or portrait, dogcow flips or not. Using initma- trix or initgraphics has two adverse consequences. Firstly it interferes with the ability of PSPrinter to generate 2-up and 4-up printing. Secondly, it pre- vents the creation of EPS files through PSPrinter. An EPS file which contains initmatrix, initclip, or initgraphics cannot be scaled, translated or rotated in an importing application. If your application generates these operators when including EPS files, users will not be able to create EPS files from your appli- cation.

See Appendix H of the PostScript Language Reference Manual, Second Edi- tion for many more tips on how to correctly include EPS files into your print stream.

4.7 Emitting Binary Data

PSPrinter itself takes advantage of a binary communications channel when it is available in order to gain improved performance. For example, printing over AppleTalk directly to a printer allows binary transmission of data. How- ever, if a spooler exists between the host Macintosh and the final destination printer, the spooler may not be able to store and forward binary data or the target printer may not be connected to the spooler via AppleTalk. To guard

4 Compatibility Issues 21 against this, PSPrinter checks that both the communication channel to the target device and a remote spooler (if it exists) can support binary data trans- mission to the target printer.

There are other circumstances when generation of binary data is unaccept- able. Users may be saving PostScript language files to disk with the ASCII option. In that case, they expect the resulting files to be portable across com- munications channels which are not transparent to binary data. To satisfy this criteria, the PostScript language code output stream generated by PSPrinter contains only characters in the printable ASCII character set plus white space.

The modular communications architecture allows new PSPrinter drivers to be built which communicate over channels other than AppleTalk. Because chan- nels such as serial and parallel communications channels to PostScript print- ers are not transparent to the full 8 bit range of characters, full binary data cannot be transmitted. A version of PSPrinter which was built to communi- cate over a serial transmission line would automatically take this into account for the PostScript language code it generates.

Application programs should not assume that the target output device can support direct binary communications. At the minimum they should allow users to indicate their preference. A better solution is to find out about the communications channel directly from PSPrinter through one of the new PrGeneral selectors available with PSPrinter (see section 5). This way an application program can take advantage of the driver’s knowledge of the communications channel and relieve the user of having to redundantly or incorrectly specify a preference.

5New PrGeneral Calls

PSPrinter adds a few new PrGeneral calls which are intended to aid applica- tions in the generation of their own PostScript language code.

The PrGeneral calls break down into 3 categories

• Obtaining the file specification corresponding to the PPD file currently associated with the target printer.

• Determining the PostScript language level and communication channel’s characteristics for the target printer

•Informing the driver of the nature of the PostScript language data the application generates.

22 Tips for Working with the New PostScript Printer Driver for Macintosh (2 Apr 93) Note: The PrGeneral calls listed in this section are present only when using PSPrinter. Specifically, they will not be emulated by QuickDraw GX and therefore will not be available to applications printing under that system. Your application should not require any of these calls, and you must be pre- pared to deal with the OpNotImpl (2) error on any of these calls.

5.1 Obtaining the PPD File for the Target Printer

PSPrinter uses PostScript Printer Description (PPD) files in order to obtain information about the features available in the target printer. This includes the list of paper sizes available and their dimensions, the number of input paper bins, and other features such as duplex printing, resolution enhancement, and fax.

PSPrinter always uses a PPD file for each printer. By default, PSPrinter uses a generic PPD file built into the driver. If a user wishes to access the special features available to their particular printer, they must first “Set Up” a printer in the Chooser by associating a PPD file with that printer. This is a one time operation for each printer available. Once set up, PSPrinter stores the infor- mation about which PPD file is the PPD file for the target printer. Subsequent selection of that printer with the Chooser causes PSPrinter to use the associ- ated PPD file automatically.

Users “Set Up” a printer in the Chooser by having PSPrinter do this automat- ically or by directly selecting a PPD file. If a user chooses “Auto Setup” in the Chooser Setup dialog, PSPrinter queries the target printer for configura- tion information such as the printer’s product name, the PostScript interpreter version number, whether the printer uses PostScript Level 2 or Level 1 soft- ware, whether the printer is a spooler, and so forth. With the target printer query information PSPrinter attempts to find the correct PPD file based on the product name and PostScript interpreter version number. If the printer is busy or the correct PPD file cannot automatically be found, users can manu- ally select a PPD file. In addition, the whole query process can be bypassed and a PPD file may be manually selected by a user. The information acquired in the automatic set up process is recorded in the database PSPrinter main- tains for each printer set up. The information recorded is the FSSpec record of the selected PPD file and also information found during the printer set up query, if it was done.

Several application programs either require a PPD file for operation or pro- vide substantially better results when a PPD file is specified. These applica- tions currently require the user to manually specify a PPD file directly. Since many PSPrinter users will have already set up their printer, thus choosing a PPD file automatically or directly in the Chooser setup, it may be desirable for an application to use the PPD file associated with the currently selected printer. PSPrinter provides a PrGeneral call allowing applications to obtain the FSSpec record for the current PPD file.

5 New PrGeneral Calls 23 The opcode PSPrimaryPPD is used for this call and the data structure passed in is filled in by PSPrinter. If the current PPD file is the driver generic built-in PPD file, rather than a real file, then the ppdIsRealFile field in the returned structure is false. A value of true means that the FSSpec record returned is a valid file and it corresponds to the PPD file for the target printer. The result- ing file specification is a real file with any aliases already resolved. For appli- cations running under system versions prior to , the data necessary for use with older file manager calls may be extracted from the FSSpec record. Note that the resulting PPD file itself may have *IncludeFile refer- ences (which also may be aliases) which must be resolved by the applica- tion’s own PPD parser. Example 4 illustrates an example of using the new PrGeneral selector PSPrimaryPPD.

Example 4: Using the PrGeneral Selector PSPrimaryPPD

enum { PSPrimaryPPD = 15 }; struct TPSPrimaryPPD { short iOpCode; short iError; long lReserved; short ppdIsRealFile;// boolean, false or true FSSpec ppdFile;// FSSpec record for the PPD file }; typedef struct TPSPrimaryPPD TPSPrimaryPPD; TPSPrimaryPPD ppd; PrOpen(); if (PrDrvrVers() >= 80 && PrDrvrVers() < 100) { /* API only available with PSPrinter */ ppd.iOpCode = PSPrimaryPPD; ppd.lReserved = 0; PrGeneral((Ptr)&ppd); if (ppd.ppdIsRealFile) { /* Only true if PPD file is not the built-in PPD */ /* ppd.ppdFile is a file spec for the main PPD file. See Inside Mac Volume VI on FSSpec records*/ } } PrClose();

5.2 Obtaining Information about the Target Printer

The new PrGeneral getPSInfo selector allows an application to determine whether the target printer supports PostScript Level 2 software, PostScript Level 1 software, or the PostScript language level is unknown. It also allows an application to determine whether the communications pathway to this printer supports Binary communications or only ASCII communications.

24 Tips for Working with the New PostScript Printer Driver for Macintosh (2 Apr 93) (PSPrinter is not always printing to a printer over a channel such as Apple- Talk which supports binary communications.) This information is intended to aid an application's efforts to generate efficient PostScript language code.

Additionally an application can determine if the output is being directed to disk and if so, whether the output format is a PostScript language file, an EPS file, or is unknown. By knowing that the output is an EPS file, Macintosh applications which normally do not generate QuickDraw output during print- ing to a PostScript printer driver can be sure to include the QuickDraw repre- sentation in order to generate a screen preview.

The PSIntentions selector allows an application (after consideration of the printer’s characteristics determined with the getPSInfo call) to inform the driver of the characteristics of the code the application generates. PSPrinter normally generates comments into the PostScript language code output stream which indicate its requirements for the document being printed. The PSIntentions selector to the PrGeneral call allows the driver to merge an application’s requirements with its own requirements. By default the driver assumes that the application will generate Level 1 code and ASCII data.

When printing to a PostScript output device, this information is determined from the database of information that the driver maintains about each printer known to it in the Chooser. This portion of the database is that generated by a query to the printer. Only data from the chooser query is used, not the cur- rently selected printer description file. If the chooser query has not been done for the target printer (because either no setup has been done or a manual setup was done by the user), then the data returned by the getPSInfo call is a language level of Unknown and a channel characteristic of ASCII. If the user is not saving to a file, then the printToFile field of the returned structure is false and the typeOfSave field is undefined and should not be used.

When saving to disk, this data is determined from the user’s selections in the save to disk dialog. Note that in either the print to disk or direct printing cases, the application must wait until PrOpenDoc has been called in order to execute this PrGeneral call. When the Level 1 Compatible option is selected in the save to disk dialog (see Figure 3) then the PrGeneral call returns lan- guage level of Level1andLevel2. This allows applications to either treat the Level 1 Compatible option as meaning the target printer is Level 1 or, as PSPrinter does, treat the case of Level 1 Compatible the same as Unknown. This approach allows applications to distinguish a truly unknown situation (such as a print spooler) from the save to disk option Level 1 Compatible. For most applications, the strategy would be identical in both cases.

When saving to disk, the printToFile field of the structure returned by the getPSInfo call is set to true. The typeOfSave field is filled in based on the format the user has selected from the save to disk dialog. If the format Post- Script Job (the default) is selected, then PSPrinter sets the typeOfSave to the

5 New PrGeneral Calls 25 value kSavePSFile. When the user selects EPS Mac¨ Standard Preview, PSPrinter sets the typeOfSave to the value kSaveEPSBitMap. When the user selects EPS Mac Enhanced Preview, PSPrinter sets the typeOfSave to the value kSaveEPSPICT. When the user selects EPS No Preview, PSPrinter sets the typeOfSave to the value kSaveEPSNoPreview. The PSPrinter initial release (version 8.0) does not support any additional EPS preview formats but future versions may. PSPrinter reserves all currently undefined positive typeOfSave values for any future EPS formats. Applications should treat any unknown positive values returned for typeOfSave other than those listed above as a type of EPS file and should generate the appropriate QuickDraw code in addition to their custom PostScript language code. This allows new selectors to be added and handled by applications in the most appropriate way.

Note that when PSPrinter reports, via the PSIntentions selector, Level 2 or binary communications support in the target printer, it does not necessarily cause PSPrinter to use such features when generating its own PostScript lan- guage output stream. For this reason applications are encouraged to conser- vatively specify their own requirements.

Note: When using the PSIntentions selector, applications should not merely pass the data obtained by the getPSInfo selector back to the driver without regard to their own needs, but instead consider the printer capabilities and the needs of the current print job. Applications are not required to call PSIn- tentions but it is strongly recommended that they do so if they generate code which requires a binary channel or requires PostScript Level 2 software in the destination device.

For example, if an application does, during a given printing session, generate PostScript Level 2 specific code with no fallback strategy for level 1 printers, it should indicate this to the driver using the PrGeneral call with the PSInten- tions selector. That is, if an application generates its PostScript language code in a manner that will fail on a Level 1 printer it should indicate that fact to the driver with this PrGeneral call. Only if an application requires a binary chan- nel should it indicate this to the driver. This allows the driver to correctly mark the output stream so that subsequent processing of the document can be done with this information available. For example, it allows post- processing software to correctly route or handle documents which require a binary com- munications channel or a Level 2 printer.

Note that there is a very high degree of probability that a job will fail if an application generates binary data when the channel only supports ASCII or if the application generates “Level 2 only” code when the target printer is a Level 1 printer.

Example 5 gives an example of how to use these new PrGeneral selectors.

26 Tips for Working with the New PostScript Printer Driver for Macintosh (2 Apr 93) Example 5: Use of PrGeneral selectors getPSInfo and PSIntentions

/* define in PrGeneral.h */ enum { getPSInfo =10, PSIntentions =11 }; enum { Level1and2 = -2, UnknownLevel = -1, OtherLevel = 0, Level1 = 1, Level2 = 2 }; enum { kSavePSUnknown = -1, kSavePSFile = 0, kSaveEPSBitMap, kSaveEPSPICT, kSaveEPSNoPreview }; #define kPSInfoVersion 1 struct TgetPSInfo { short iOpCode; short iError; long lReserved; struct TPrint **hPrint; short version; short level; short typeOfSave; unsigned short printToFile : 1; unsigned short binary : 1; unsigned short reserved : 14; }; typedef struct TgetPSInfo TgetPSInfo; #define kPSIntentionsVersion 1 struct TPSIntentions { short iOpCode; short iError; long lReserved; struct TPrint **hPrint; short version; short level; unsigned short binary : 1; unsigned short reserved : 15; }; typedef struct TPSIntentions TPSIntentions; /* end excerpt PrGeneral.h file */

void MyPrint(THPrint ph) { TgetPSInfo getInfo; TPSIntentions intentions; TPPrPort pport;

5 New PrGeneral Calls 27 PrOpen(); if (PrJobDialog(ph) && (PrDrvrVers()>= 80) && (PrDrvrVers()< 100) ) { pport = PrOpenDoc(ph, 0, 0); /* get information */ getInfo.iOpCode = getPSInfo; getInfo.hPrint = ph; /* getPSInfo must know version */ getInfo.version = kPSInfoVersion ; PrGeneral((Ptr)&getInfo); /* here we can check returned version against what we expect */ if (getInfo.version >= kPSInfoVersion ) { /* usage of getInfo.level, getInfo.binary, getInfo.typeOfSave, getInfo.printToFile goes here */ } /* now tell driver about our intentions */ intentions.iOpCode = PSIntentions; intentions.hPrint = ph; intentions.version = kPSIntentionsVersion ;

/* use Level2 and/or binary only if required and printer supports it!!! this code should check the results of the getPSInfo before setting and using these fields!!! */

intentions.level = Level2; intentions.binary = true; intentions.reserved = 0;

PrGeneral((Ptr)&intentions); /* rest of printing */ } PrClose(); }

6 References

This section attempts to list references which are useful for application writ- ers working to ensure compatibility with new printer drivers, particularly PostScript printer drivers such as PSPrinter.

6.1 General References

The standard reference for printing from Macintosh applications is Inside Macintosh, published by Addison-Wesley. The chapters on printing are in Inside Mac Volume II, Chapter 5, The Printing Manager and Inside Mac Volume V, Chapter 22, The Printing Manager.

Additionally, Apple has published a number of articles in their Macintosh Technical Notes which focus on printing. Those of general interest are

28 Tips for Working with the New PostScript Printer Driver for Macintosh (2 Apr 93) •Macintosh Technical Note A Printing Loop That Cares (old #161). This technical note gives a full blown print loop which carefully handles errors.

•Macintosh Technical Note PrGeneral (old #128).

•Macintosh Technical Note Every Picture [Comment] Tells Its Story, Don’t It (old #181).

•Macintosh Technical Note Pictures and the Printing Manager (old #297).

Of particular interest to PostScript printer drivers:

•Macintosh Technical Note Picture Comments–The Real Deal (old #91). The latest version of this technical note gives much expanded information for application writers and is dated November 1992 (or later). It gives details on the picture comments originally defined by the Apple Laser- Writer driver. These comments include those necessary to pass custom PostScript language code through the driver to the output stream. Also included are comments to rotate text and graphics, set a fractional line width while drawing lines, draw dashed lines, and to smooth polygons.

•Macintosh Technical Note Using Laser Prep Routines (old #152). This technical note discusses application usage of LaserPrep routines (i.e. DON’T USE THEM!).

•Macintosh Technical Note Fun with PrJobMerge (old #312). This techni- cal note discusses bugs in PrJobMerge in LaserWriter driver 7.0 and 7.1. These bugs have been fixed in PSPrinter.

Apple has also published a number of articles in their d e v e l o p journal focusing on printing and ‘print crimes’.

• d e v e l o p Issue 1, The Perils of PostScript

• d e v e l o p Issue 3, Meet PrGeneral

• d e v e l o p Issue 4, Perils of PostScript II

• d e v e l o p Issue 10, Printing Hits: Top 10 Printing Crimes

6.2 PostScript Language References

The reference specification for the PostScript language is the PostScript Lan- guage Reference Manual, Second Edition. This latest edition includes infor- mation on PostScript Level 2 software in addition to PostScript Level 1

6 References 29 software and extensions for the Display PostScript™ system. The PostScript Language Reference Manual also contains appendices which are relevant to writers of PostScript language code through PSPrinter and other PostScript printer drivers. These include:

Appendix D, Compatibility Strategies

This appendix discusses general strategies for supporting both PostScript Level 2 and Level 1 output devices simultaneously without generating Post- Script language errors or other problems. There is greatly expanded informa- tion on this topic in Adobe’s PostScript Language Software Development Kit.

Appendix G, Document Structuring ConventionsÐVersion 3.0

This appendix discusses conventions developed by Adobe Systems to add structure to PostScript language documents in order to improve the handling of such electronic documents. These conventions are strictly adhered to by the PostScript language code produced by PSPrinter. Applications which generate their own custom PostScript language code into the print stream are strongly encouraged to follow these guidelines.

Appendix H, Encapsulated PostScript File FormatÐVersion 3.0

This appendix discusses the EPS specification, version 3.0. It contains infor- mation about the generation of EPS files as well as how to import them into your application. Section H.3 provides careful guidelines and examples of how to set up the PostScript language coordinate system you need for proper sizing and orientation of EPS files your application imports.

Appendix I, Guidelines for Specific Operators

This appendix discusses operators in the PostScript language whose usage requires extra care. Many of the operators in this section should not appear in a device independent page description or an EPS file. Such operators include initgraphics, initclip or initmatrix. This appendix goes into detail discussing the problems associated with the use of such operators.

In addition, Adobe Developer Support has written a document Tips for Spooler Writers - Technical Note #5133 specifically for writers of PostScript language spoolers. This document contains information about how to handle queries from PostScript printer drivers, especially Adobe’s PostScript printer driver for the Macintosh, PSPrinter.

30 Tips for Working with the New PostScript Printer Driver for Macintosh (2 Apr 93) Index

Numerics M

2-pass design 8 md dictionary 9, 12

B N background printing 9 n-up printing 7, 10, 17, 21 binary communications 26 Binary Data 21 P C paper bins 23 PICT preview 18, 19, 20 clip 10, 13, 15, 16 PostScript Level 2 6, 23 PostScript PicComments 14 D PostScript Printer Description 10, 17, 22 Document Structuring Conventions PostScriptBegin 13, 21 7, 10, 17 PostScriptBeginNoSave 14, 15, 16 PrDrvrVers 12 E PREC 103 17 PrGeneral 6, 18, 20, 22, 23, 25 Encapsulated PostScript File 6, 18 print crimes 11 print record 11 F PrJobDialog 11 FlushQDState 14, 16, 19 PrStlDialog 11 psb 16 G pse 16 PSIntentions 26 getPSInfo 24, 25, 26 PSPrimaryPPD 24

I Q initclip 10, 19 QuickDraw GX 11, 23 initgraphics 19, 21 QuickDraw state 13 initmatrix 19, 21 S L setpagedevice 17, 18 LaserPrep 12 setpageparams 17, 18 StdComment 13

31 T

TextIsPostScript 20

32 Index (2 Apr 93)