Chapter 9. Printing

Printing is one of the basic functions provided by most applications. When printing a document, a user may first wish to specify settings such as the page size and orientation, the scaling percentage, the page range, and the number of copies. A user may also wish to specify a printer from a list of available printers and choose settings specific to that printer, such as paper tray, duplex printing, or print quality. The application itself may supply additional printing options, such as whether to print odd or even numbered pages or registration marks. If the user doesn’t specifically choose any setting, the application should supply reasonable default values if possible.

Because printing involves many variables, your application may have a lot of work to do to deliver robust printing support. However, Mac OS X provides features to help your application gather and work with printing information. These features involve interaction that takes place between the user, the application, the operating system, and the printer:

  • Your application can call on Mac OS X to display the Page Setup dialog, shown in Figure 9.1. The Page Setup dialog lets the user choose page format settings, such as paper size, orientation, and scale, before printing. You can save these settings with a document and use them again when the document is reopened.

    The Page Setup dialog, showing default values

    Figure 9-1. The Page Setup dialog, showing default values

  • When a user chooses to print a document, your application calls on Mac OS X to display the Print dialog, shown in Figure 9.2. The Print dialog lets the user choose print settings, such as the printer, page range, and number of copies. Applications can extend both the Page Setup and Print dialogs to add application-specific options, and printer manufacturers can also extend the Print dialog with printer-specific options.

    The Print dialog, showing default values

    Figure 9-2. The Print dialog, showing default values

  • Mac OS X provides printing data types to keep track of user selections in the Page Setup and Print dialogs. Your application uses instances of these data types in calls to printing functions. You can extend some of these types with your own data, save them with documents, and use them when the document is opened and printed.

In this chapter you’ll learn about the Carbon Printing Manager, which can help your application supply powerful printing support with a consistent user experience. You’ll learn key concepts for printing with the Carbon Printing Manager, including:

  • How to organize a printing session

  • How to set up a print loop to print a range of pages

  • How to handle printing errors

You’ll also write printing code for the Moon Travel Planner application. Once you’re familiar with the printing concepts described in this chapter, you should be able to adapt them for printing in other Carbon applications you write.

The Carbon Printing Manager

Mac OS X includes a flexible new printing system based on a modular client/server architecture. The printing system:

  • Uses PDF-based rendering, providing PDF capability for all printers, including inexpensive raster printers

  • Allows applications to draw in “virtual pages” and map those pages to “physical pages” at print time, breaking the connection between the drawing page and the printing page

  • Provides applications and printer drivers with control over individual user interface elements in the system’s printing dialog boxes, so applications and drivers don’t need to completely replace the standard Print or Page Setup dialog boxes with custom versions

  • Includes robust support for Carbon applications through the Carbon Printing Manager

In Mac OS X, Carbon applications can initiate multiple, simultaneous printing tasks. Each printing task is referred to as a printing session, and each printing session is independent of other printing sessions. Printing sessions can run in separate threads, or you can create multiple sessions within a single-threaded application. You’ll read more about threads in Chapter 14.

Note

The Carbon Printing Manager was designed to let Carbon applications take advantage of new features in Mac OS X, while still working correctly in previous versions of the Mac OS. For example, the Carbon Printing manager supports printing sessions on Mac OS 8 and 9, although each application can have only one printing session running in a single thread, due to limitations of the underlying Classic printing architecture.

This book doesn’t cover how to create a Carbon application that can run on versions of the Mac OS earlier than Mac OS X, although the printing code in this chapter should compile and run on either platform. If you want to write an application that can run and print on both platforms, see the Carbon Porting Guide in Carbon Help (available in the Project Builder Help menu).

Carbon Printing Manager functions can conceptually be divided into three groups:

  • Session functions. These can create and manage printing sessions.

  • Nonsession functions. These don’t support sessions. They operate identically on all Carbon platforms, but inherit some of the limitations of the Classic Printing Manager.

  • Universal functions. These are available with both session and nonsession printing functions.

The rest of this chapter will deal only with the universal and session functions, which are strongly recommended for all Carbon applications.

A Sample Printing Session

For any printing session, an application will need to:

  • Instantiate a Carbon Printing Manager printing session object for the session

  • Instantiate a Carbon Printing Manager page format object to store information from the Page Setup dialog, such as paper size and orientation

  • Instantiate a Carbon Printing Manager print settings object to store information from the Print dialog, such as page range and number of copies

  • Instantiate an application-defined data type (call it the AppPrintInfo structure) to store printing information, including references to the three previous objects, plus additional information such as pointers to application printing data and functions

  • Provide certain printing functions, such as a function to draw one page of a document

The data types for printing session, page setup, and print settings objects are described in detail in Section 9.1.3 and Carbon Printing Manager functions are described in more detail in Section 9.1.4.

Note

The main Carbon Printing Manager data types you’ll use are PMPrintSession, PMPageFormat, and PMPrintSettings. The Carbon Printing Manager provides functions to extend these opaque data types to contain data you supply, but you won’t do that here. Although instances of these types are sometimes referred to as objects, that doesn’t mean you’ll have to write any object-oriented code. The Carbon Printing Manager hides the underlying implementation and provides procedural functions to access the internal data of these structures. But of course you can freely call these functions from object-oriented code.

As you work through this sample printing session, you’ll see a number of data objects and functions. Functions that start with PM are Carbon Printing Manager functions; those that start with App must be defined by your application. Later sections will provide additional information about the Carbon Printing Manager functions and data types mentioned here. To see a full implementation of a printing session for a working application, see Section 9.2.

Suppose a user opens a text document in the application. Your application would perform steps similar to the following:

  • Create a window to display the document information.

  • Create an instance of the AppPrintInfo structure and store it with the window. If your application stores page format information with the document, extract it, call PMUnflattenPageFormat to create a page format object, and store a reference to the object in the AppPrintInfo structure; otherwise, store an empty reference for now. Store empty references for a printing session object and for a print settings object in the AppPrintInfo structure. Your application will create the objects when needed for printing. Store references to various application functions that will be called during printing, such as the AppDrawPage function, in the AppPrintInfo structure.

  • If the user chooses Page Setup from the File menu, call PMCreateSession to create a printing session object. Also call PMCreatePageFormat to create a page format object, if one hasn’t already been created, and call PMSessionDefaultPageFormat to set it to default values for this session. If the page format object already exists, call PMSessionValidatePageFormat to ensure that the object is valid within the context of the printing session. Call PMSessionUseSheets to indicate the Page Setup dialog should use sheets (a Mac OS X feature in which a printing dialog is attached to the window of the document being printed). Call PMSessionPageSetupDialog to display the Page Setup dialog. Preserve page setup information in the page format object. When the Page Setup dialog is dismissed, call PMRelease to release the session object.

  • If the user chooses Print from the File menu, create a session object and set up a page format object (creating it if necessary) as in the previous step. Call PMCreatePrintSettings to create a print settings object and call PMSessionDefaultPrintSettings to set it to default values for this session. Call PMSessionUseSheets to indicate the Print dialog should use sheets. Call the Carbon Printing Manager function PMSessionPrintDialog to display the Print dialog.

  • If the user accepts the Print dialog, call a print loop function, passing the AppPrintInfo structure to provide the data needed for printing. Call PMGetFirstPage and PMGetLastPage to get the user-specified page range, and call AppPagesInDoc to verify the legal page range. Call PMSessionBeginDocument to begin the print job. Loop over the user-specified page range, calling PMSessionBeginPage and calling your application’s AppDrawPage function to print each page and PMSessionEndPage on completion. After printing, or after the user cancels the print job, call PMSessionEndDocument to end the print job and PMRelease to release the print settings and printing session objects.

  • When the user saves the document, most applications save the page format data (choices made by the user on the Page Setup dialog) with the document. Your application can use the PMSetPageFormatExtendedData function to store application-specific information with the page format data.

The next section takes a more detailed look at the print loop function and the Carbon Printing Manager functions it typically calls.

A look at the print loop

The print loop is simply the piece of code that calls all the necessary functions to print a selected page range of a document. By the time the print loop function is called, your application has performed some preparation for printing, as described in the previous section: your application has created and initialized its own print information structure; it has created Carbon Printing Manager objects for the printing session, page format, and print settings; and your application’s print information structure has references to these objects.

The user may have used the Page Setup dialog to change page format options. Finally, the user has displayed the Print dialog and decided to print all or a range of pages. Your application calls the print loop function, passing a pointer to the print information structure. The following pseudocode shows the calls a typical print loop might make, with the calls divided among Carbon Printing Manager functions, other Carbon functions, and application-defined functions. Not all error handling is shown, but the print loop should check for errors after each call that may return one:

AppPagesInDoc (application function to verify legal page range)
PMGetFirstPage (get the selected page range, first to last)
PMGetLastPage (adjust if selected range outside legal range)
(now know how many pages to print in the print loop)
PMSetFirstPage (set page range that will show up in progress dialog)
PMSetLastPage
PMSessionBeginDocument (begin a new print job)
    (for each page to be printed)
    PMSessionError (check for an error before starting a new page;
                    if error, break out of loop)
    PMSessionBeginPage (prepare to print the current page)
        PMSessionGetGraphicsContext (get printing port)
        SetPort (Carbon function to set current drawing port 
                    to printing port)
        AppDrawPage (application function to draw one page)
        SetPort (Carbon function to restore saved port)
    PMSessionEndPage (finish printing current page)
PMSessionEndDocument (end the print job)
AppPostPrintingErrors (application function to display any error to user)
PMRelease (release print settings and printing session objects)

This print loop adheres to requirements described in Section 9.1.2 as well as to the error handling described in Section 9.1.1.2. You’ll notice that very few of the functions called in the print loop are application-defined functions—most are Carbon Printing Manager functions or other Carbon functions. Your application supplies functions only to determine the maximum number of pages in its document, to print one page, and to display errors (if any).

For a full-scale print loop from a working application, see the MTPDoPrintLoop function in Section 9.2.

Error handling

Your application should always check for error conditions while printing. As usual, you should check for an error from every function that can return one. Within a print loop that uses Carbon Printing Manager session functions, as described in this chapter, you should also check for errors by calling PMSessionError before beginning each new page. If PMSessionError returns a value other than noErr, you should quit printing and close the page and document (depending on the location of the error). If the error value is anything other than kPMCancel (which indicates the user canceled printing), you should also display an error alert to the user.

For a simplified implementation of this type of error handling, see the descriptions for the MTPDoPrintLoop and MTPPostPrintingErrors functions in Section 9.2.

Sequence and Scope for Printing Functions

The application code that prints a range of pages is called a print loop because it loops to print each page in the range. The Carbon Printing Manager enforces a sequence of steps in a print loop and defines a valid scope for each printing function. This means that your application must call certain functions before calling others. Functions used out of sequence generate an error value of kPMOutOfScope. The rules for calling sequence and scope are different for session and nonsession printing functions. This section provides a brief overview of the requirements for session printing. For additional details, see the Carbon Printing Manager documentation in Carbon Help (available in the Project Builder Help menu).

The following list of functions shows the calling sequence and scope requirements for some of the most commonly used session functions:

PMCreateSession
    PMSessionDefaultPageFormat
    PMSessionValidatePageFormat
    PMSessionDefaultPrintSettings
    PMSessionValidatePrintSettings
    PMSessionUseSheets
    PMSessionPageSetupDialog
    PMSessionPrintDialog
    PMSessionBeginDocument
        PMSessionBeginPage
            PMSessionGetGraphicsContext
        PMSessionEndPage
    PMSessionEndDocument
PMRelease

In general, functions may be called in any order with respect to other functions at the same or lower scope level (represented in the list by indentation). For example, you can call PMSessionGetGraphicsContext only within the scope of a call to PMSessionBeginPage, which in turn must be within the scope of a call to PMSessionBeginDocument. But within the scope of a call to PMCreateSession, you can call PMSessionDefaultPageFormat and PMSessionDefaultPrintSettings in any order.

Note

The series of steps between the function calls to PMSessionPrintDialog and PMSessionEndDocument (that is, from the display of the Print dialog until the last page is printed in the print loop) is commonly refered to as a print job.

Naturally “begin” functions (such as PMSessionBeginPage) must be called before their corresponding “end” functions (PMSessionEndPage). And some calls make sense only in a certain order within a given scope. For example, if you are using sheets, as the code in this chapter does, you must call PMSessionUseSheets before calling the PMSessionPageSetupDialog or PMSessionPrintDialog function to display a dialog as a sheet.

The following list shows some of the universal printing functions, which can be called at any time:

PMCreatePageFormat
PMCreatePrintSettings
PMFlattenPageFormat
PMUnflattenPageFormat
PMGetPageFormatExtendedData
PMSetPageFormatExtendedData
PMGetAdjustedPaperRect
PMGetAdjustedPageRect
PMGetOrientation
PMSetOrientation
PMFlattenPrintSettings
PMUnflattenPrintSettings
PMGetPageRange
PMSetPageRange

Although these functions are designed to be called at any time, it is currently required that you call PMSessionValidatePageFormat before calling PMGetAdjustedPaperRect or PMGetAdjustedPageRect.

Many of these functions are used in the sample code in this chapter. Two functions that are not used, but that may be of interest, are PMFlattenPageFormat and PMUnflattenPageFormat. You can use these functions to save and restore information from the opaque PMPageFormat data structure, which stores information displayed in the Page Setup dialog (shown in Figure 9.1). You use PMFlattenPageFormat, for example, to flatten a page format object before writing it to a handle, document, or other location, and PMUnflattenPageFormat to recreate a PMPageFormat object after reading flattened data.

Because you can use the PMSetPageFormatExtendedData function to store application data with a page format object and the PMGetPageFormatExtendedData function to retrieve the data, the PMFlattenPageFormat and PMUnflattenPageFormat functions provide a convenient way to save and restore additional application-specific data along with the standard page format data.

The functions PMFlattenPrintSettings and PMUnflattenPrintSettings perform a similar duty for saving and restoring information from the opaque PMPrintSettings data structure, which stores information displayed in the Print dialog (shown in Figure 9.2). However, most applications will not need to save settings information. An application can extend a print settings object with the PMSetPrintSettingsExtendedData and PMGetPrintSettingsExtendedData functions.

An application can extend an instance of the PMPrintSession data type with the PMSessionSetDataInSession and PMSessionGetDataFromSession functions, but the Carbon Printing Manager does not supply functions to flatten and unflatten an instance of this type. Therefore, you can use the extended data structure only within the lifetime of the printing session object (before releasing it).

Data Types for Working with Printing Sessions

Don’t look for direct access to global data structures in the Carbon Printing Manager—that’s so 20th century. Instead, the Carbon Printing Manager relies primarily on the opaque data structures shown in Table 9.1. The table also shows the functions you use to create these data types and, for those that can be extended to store application-specific data, the functions for extending them. Each of the creation functions returns a reference to an instance of the specified data type.

Table 9-1. Printing Session Data Types

Data typeCreate with/extend withDescription
PMPrintSession

PMCreateSession / PMSessionSetDataInSession PMSessionGetDataFromSession

Represents a single printing session.

PMPageFormat

PMCreatePageFormat / PMSetPageFormatExtendedData PMGetPageFormatExtendedData

Stores information about how pages of a document should be printed, such as paper size and orientation.

PMPrintSettings

PMCreatePrintSettings / PMSetPrintSettingsExtendedData PMGetPrintSettingsExtendedData

Stores such information as the print quality and the range of pages to print for a particular print job.

PMPrinter

PMSessionGetCurrentPrinter

Represents a printer. May contain such data as resolution, driver creator, and language information for the printer. Many applications won’t need to use this data type.

Previous sections provided examples of how to use these data types. The next section provides information on functions that work with these types.

Functions for Working with Printing Sessions

Because the primary printing data types for printing sessions are opaque, you cannot directly access any of their internal data. Instead, the Carbon Printing Manager defines accessor functions for manipulating the data in these structures. Table 9.2 shows some of the accessors and other functions available to work with an instance of the opaque data type PMPrintSession.

The Carbon Printing Manager doesn’t supply functions for saving an instance of a printing session because it’s not recommended that you save one. An application typically creates an instance of a printing session as needed (such as before displaying the Page Setup or Print dialog) and releases it when it is no longer needed (as when the print loop has completed).

Table 9-2. Functions for Working with the PMPrintSession Data Type

FunctionDescription
PMCreateSession

Initializes a PMPrintSession object and creates a context for printing operations for a single printing session.

PMRelease

Decrements the reference count for a printing object (such as an instance of a session, page setup, or print settings data type). When an object’s reference count reaches 0, the object is deallocated.

PMSessionBeginDocument

Establishes a new print job.

PMSessionEndDocument

Closes the print job started with PMSessionBeginDocument.

PMSessionBeginPage

Informs the printing system that the drawing that follows is part of a new page.

PMSessionEndPage

Finishes printing the current page.

PMSessionGetCurrentPrinter

Obtains a reference to the PMPrinter object for the current printer.

PMSessionGetDataFromSession PMSessionSetDataInSession

Obtains (or sets) the data the application previously stored in a printing session object.

PMSessionGetGraphicsContext

Obtains the graphics context associated with the current page.

PMSessionPageSetupDialog

Displays the Page Setup dialog and records the user’s selections in a PMPageFormat object.

PMSessionPrintDialog

Displays the Print dialog and records the user’s selections in a PMPrintSettings object.

PMSessionUseSheets

Specifies that a printing dialog be displayed as a sheet (that is, attached to the window of the document being printed).

Table 9.3 shows some of the accessors and other functions available to work with an instance of the opaque data type PMPageFormat, which is used to store information displayed in the Page Setup dialog. Applications typically store page format information with documents and also maintain it between printing sessions, because users expect changes made in the Page Setup dialog to persist with the document. The table describes functions for creating an instance of this data type, setting it to default values, validating it for the current printing session, extracting information from it, and so on.

Table 9-3. Functions for Working with the PMPageFormat Data Type

FunctionDescription
PMCreatePageFormat

Creates a new PMPageFormat object.

PMSessionDefaultPageFormat

Assigns default parameter values for the specified printing session to an existing PMPageFormat object.

PMSessionValidatePageFormat

Ensures that a PMPageFormat object is valid within the context of the specified printing session.

PMFlattenPageFormat

Flattens a PMPageFormat object for storage in a user document or other location.

PMUnflattenPageFormat

Creates a PMPageFormat object from a flattened representation produced previously by PMFlattenPageFormat.

PMGetPageFormatExtendedData PMSetPageFormatExtendedData

Obtains (or sets) extended page format data for the application.

PMGetAdjustedPageRect PMSetAdjustedPageRect

Obtains (or sets) the page size, taking into account orientation, application drawing resolution, and scaling settings.

PMGetAdjustedPaperRect PMSetAdjustedPaperRect

Obtains (or sets) the paper size, taking into account orientation, application drawing resolution, and scaling settings.

PMGetScale, PMSetScale

Obtains (or sets) the scaling factor currently applied to the page and paper rectangles.

Table 9.4 shows some of the accessors available to work with an instance of the opaque data type PMPrintSettings, which is used to store information displayed in the Print dialog. Applications don’t typically store print settings information, because users expect the Print dialog to show current default values. The table describes functions for creating an instance of this data type, setting it to default values, validating it for the current printing session, extracting information from it, and so on.

Note

The Print dialog contains a Saved Settings pop-up menu that lets users select from various saved settings, so most applications shouldn’t need to worry about saving settings themselves.

Table 9-4. Functions for Working with the PMPrintSettings Data Type

FunctionDescription
PMCreatePrintSettings

Creates a new PMPrintSettings object.

PMSessionDefaultPrintSettings

Assigns default parameter values for the specified printing session to an existing PMPrintSettings object.

PMSessionValidatePrintSettings

Ensures that a PMPrintSettings object is valid within the context of the specified printing session.

PMFlattenPrintSettings

Flattens a PMPrintSettings object for storage in a user document or other location.

PMUnflattenPrintSettings

Creates a PMPrintSettings object from a flattened representation produced previously by PMFlattenPrintSettings.

PMGetPrintSettingsExtendedData PMSetPrintSettingsExtendedData

Obtains (or sets) extended print settings data for the application.

PMGetCopies, PMSetCopies

Obtains (or sets) the number of copies that the user has requested to be printed.

PMGetFirstPage, PMSetFirstPage

Obtains (or sets) the number of the first page to be printed.

PMGetLastPage, PMSetLastPage

Obtains (or sets) the number of the last page to be printed.

PMGetPageRange, PMSetPageRange

Obtains (or sets) the valid range of pages that can be printed.

Where to Go from Here

This section should have provided a good description of the basic concepts you’ll use to print with the Carbon Printing Manager. If you’re working on an application with complex printing needs, see the following:

  • For more information on the Mac OS X printing architecture, see Inside Mac OS X: System Overview, available in Carbon Help (available in the Project Builder Help menu).

  • For additional information on printing, see the Carbon Printing Manager documentation in Carbon Help.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.219.34.62