Retired Document
Important: This sample code may not represent best practices for current development. The project may use deprecated symbols and illustrate technologies and techniques that are no longer recommended.
print.c
/* |
File: print.c |
Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Computer, Inc. |
("Apple") in consideration of your agreement to the following terms, and your |
use, installation, modification or redistribution of this Apple software |
constitutes acceptance of these terms. If you do not agree with these terms, |
please do not use, install, modify or redistribute this Apple software. |
In consideration of your agreement to abide by the following terms, and subject |
to these terms, Apple grants you a personal, non-exclusive license, under AppleÕs |
copyrights in this original Apple software (the "Apple Software"), to use, |
reproduce, modify and redistribute the Apple Software, with or without |
modifications, in source and/or binary forms; provided that if you redistribute |
the Apple Software in its entirety and without modifications, you must retain |
this notice and the following text and disclaimers in all such redistributions of |
the Apple Software. Neither the name, trademarks, service marks or logos of |
Apple Computer, Inc. may be used to endorse or promote products derived from the |
Apple Software without specific prior written permission from Apple. Except as |
expressly stated in this notice, no other rights or licenses, express or implied, |
are granted by Apple herein, including but not limited to any patent rights that |
may be infringed by your derivative works or by other works in which the Apple |
Software may be incorporated. |
The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO |
WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED |
WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN |
COMBINATION WITH YOUR PRODUCTS. |
IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR |
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE |
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION |
OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT |
(INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN |
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
Copyright © 2002 Apple Computer, Inc., All Rights Reserved |
*/ |
#include "atsui.h" |
#include "print.h" |
// Globals (for this source file only) |
// |
static Handle gflatPageFormat = NULL; // used in FlattenAndSavePageFormat |
static PMPageFormat gPageFormat = kPMNoPageFormat; |
static PMPrintSettings gPrintSettings = kPMNoPrintSettings; |
static PMPrintSession gPrintSession; |
/*------------------------------------------------------------------------------ |
Function: InitializePrinting |
Parameters: |
none |
Description: |
Creates a print session to be used throughout the application. Also |
creates a default page format, which allows the user to choose "Print" |
from the menu without having done "Page Setup" first. |
------------------------------------------------------------------------------*/ |
OSStatus InitializePrinting(void) |
{ |
OSStatus status; |
// Initialize the print session |
// |
status = PMCreateSession(&gPrintSession); |
// Create the page format |
// |
status = PMCreatePageFormat(&gPageFormat); |
// Note that PMPageFormat is not session-specific, but calling |
// PMSessionDefaultPageFormat assigns values specific to the printer |
// associated with the current printing session. |
// |
if ( (status == noErr) && (gPageFormat != kPMNoPageFormat) ) { |
status = PMSessionDefaultPageFormat(gPrintSession, gPageFormat); |
} |
return status; |
} |
/*------------------------------------------------------------------------------ |
Function: DoPageSetupDialog |
Parameters: |
printSession - current printing session |
pageFormat - a PageFormat object addr |
Description: |
If the caller passes in an empty PageFormat object, DoPageSetupDialog |
creates a new one, otherwise it validates the one provided by the caller. |
It then invokes the Page Setup dialog and checks for Cancel. Finally it |
flattens the PageFormat object so it can be saved with the document. |
Note that the PageFormat object is modified by this function. |
------------------------------------------------------------------------------*/ |
OSStatus DoPageSetupDialog(void) |
{ |
OSStatus status; |
Boolean accepted; |
// Set up a valid PageFormat object. |
// |
if ( gPageFormat == kPMNoPageFormat ) { |
status = PMCreatePageFormat(&gPageFormat); |
// Note that PMPageFormat is not session-specific, but calling |
// PMSessionDefaultPageFormat assigns values specific to the printer |
// associated with the current printing session. |
if ( (status == noErr) && (gPageFormat != kPMNoPageFormat) ) { |
status = PMSessionDefaultPageFormat(gPrintSession, gPageFormat); |
} |
} |
else { |
status = PMSessionValidatePageFormat(gPrintSession, gPageFormat, kPMDontWantBoolean); |
} |
// Display the Page Setup dialog. |
// |
if ( status == noErr ) { |
status = PMSessionPageSetupDialog(gPrintSession, gPageFormat, &accepted); |
if ( ! accepted ) { |
status = kPMCancel; // user clicked Cancel button |
} |
} |
// If the user did not cancel, flatten and save the PageFormat object |
// with our document. |
// |
if (status == noErr ) { |
status = FlattenAndSavePageFormat(gPageFormat); |
} |
return status; |
} // DoPageSetupDialog |
/*------------------------------------------------------------------------------ |
Function: DoPrintDialog |
Parameters: |
printSession - current printing session |
pageFormat - a PageFormat object addr |
printSettings - a PrintSettings object addr |
Description: |
If the caller passes an empty PrintSettings object, DoPrintDialog creates |
a new one, otherwise it validates the one provided by the caller. |
It then invokes the Print dialog and checks for Cancel. |
Note that the PrintSettings object is modified by this function. |
------------------------------------------------------------------------------*/ |
OSStatus DoPrintDialog(void) |
{ |
OSStatus status; |
Boolean accepted; |
UInt32 realNumberOfPagesinDoc; |
// In this sample code the caller provides a valid PageFormat reference but in |
// your application you may want to load and unflatten the PageFormat object |
// that was saved at PageSetup time. See LoadAndUnflattenPageFormat below. |
// Set up a valid PrintSettings object. |
if (gPrintSettings == kPMNoPrintSettings) { |
status = PMCreatePrintSettings(&gPrintSettings); |
// Note that PMPrintSettings is not session-specific, but calling |
// PMSessionDefaultPrintSettings assigns values specific to the printer |
// associated with the current printing session. |
if ((status == noErr) && (gPrintSettings != kPMNoPrintSettings)) { |
status = PMSessionDefaultPrintSettings(gPrintSession, gPrintSettings); |
} |
} |
else { |
status = PMSessionValidatePrintSettings(gPrintSession, gPrintSettings, kPMDontWantBoolean); |
} |
// Before displaying the Print dialog, we calculate the number of pages in the |
// document. On Mac OS X this is useful because we can prime the Print dialog |
// with the actual page range of the document and prevent the user from entering |
// out-of-range numbers. This is not possible on Mac OS 8 and 9 because the driver, |
// not the printing manager, controls the page range fields in the Print dialog. |
// Calculate the number of pages required to print the entire document. |
if (status == noErr) { |
status = DetermineNumberOfPagesInDoc(gPageFormat, &realNumberOfPagesinDoc); |
} |
// Set a valid page range before displaying the Print dialog |
if (status == noErr) { |
status = PMSetPageRange(gPrintSettings, 1, realNumberOfPagesinDoc); |
} |
// Display the Print dialog. |
if (status == noErr) { |
status = PMSessionPrintDialog(gPrintSession, gPrintSettings, gPageFormat, &accepted); |
if (!accepted) { |
status = kPMCancel; // user clicked Cancel button |
} |
} |
return status; |
} // DoPrintDialog |
/*------------------------------------------------------------------------------ |
Function: |
DoPrintLoop |
Parameters: |
printSession - current printing session |
pageFormat - a PageFormat object addr |
printSettings - a PrintSettings object addr |
Description: |
DoPrintLoop calculates which pages to print and executes the print |
loop, calling DrawPage for each page. |
------------------------------------------------------------------------------*/ |
void DoPrintLoop(void) |
{ |
OSStatus status, |
printError; |
GrafPtr currPort, printingPort; |
UInt32 realNumberOfPagesinDoc, |
pageNumber, |
firstPage, |
lastPage; |
CFStringRef jobName = CFSTR("ATSUITestApp"); |
// Since this sample code doesn't have a window, give the spool file a name. |
status = PMSetJobNameCFString(gPrintSettings, jobName); |
// Get the user's Print dialog selection for first and last pages to print. |
if (status == noErr) { |
status = PMGetFirstPage(gPrintSettings, &firstPage); |
if (status == noErr) { |
status = PMGetLastPage(gPrintSettings, &lastPage); |
} |
} |
// Check that the selected page range does not exceed the actual number of |
// pages in the document. |
if (status == noErr) { |
status = DetermineNumberOfPagesInDoc(gPageFormat, &realNumberOfPagesinDoc); |
if (realNumberOfPagesinDoc < lastPage) { |
lastPage = realNumberOfPagesinDoc; |
} |
} |
// Before executing the print loop, tell the Carbon Printing Manager which pages |
// will be spooled so that the progress dialog can reflect an accurate page count. |
// This is recommended on Mac OS X. On Mac OS 8 and 9, we have no control over |
// what the printer driver displays. |
if (status == noErr) { |
status = PMSetFirstPage(gPrintSettings, firstPage, false); |
} |
if (status == noErr) { |
status = PMSetLastPage(gPrintSettings, lastPage, false); |
} |
// Note, we don't have to worry about the number of copies. The printing |
// manager handles this. So we just iterate through the document from the |
// first page to be printed, to the last. |
if (status == noErr) { |
// Establish a graphics context for drawing the document's pages. |
status = PMSessionBeginDocument(gPrintSession, gPrintSettings, gPageFormat); |
if (status == noErr) { |
// Print the selected range of pages in the document. |
pageNumber = firstPage; |
while ((pageNumber <= lastPage) && (PMSessionError(gPrintSession) == noErr)) { |
// Note, we don't have to deal with the classic Printing Manager's |
// 128-page boundary limit. |
// Set up a page for printing. Under the classic Printing Manager, applications |
// could provide a page rect different from the one in the print record to achieve |
// scaling. This is no longer recommended and on Mac OS X, the PageRect argument |
// is ignored. |
status = PMSessionBeginPage(gPrintSession, gPageFormat, NULL); |
if (status != noErr) { |
break; |
} |
// Save the current QD grafport. |
GetPort(&currPort); |
// Get the current graphics context, in this case a Quickdraw grafPort, |
// for drawing the page. |
status = PMSessionGetGraphicsContext(gPrintSession, kPMGraphicsContextQuickdraw, (void**) &printingPort); |
if (status == noErr) { |
// Set the printing port before drawing the page. |
SetPort((GrafPtr) printingPort); |
// Draw the page. |
//DrawPage(gPrintSession, pageNumber, addPostScript); |
DrawATSUIStuff((GrafPtr) printingPort); |
// Restore the QD grafport. |
SetPort(currPort); |
} |
// Close the page. |
status = PMSessionEndPage(gPrintSession); |
if (status != noErr) { |
break; |
} |
// And loop. |
pageNumber++; |
} |
// Close the printing port. This dismisses the progress dialog on Mac OS X. |
(void)PMSessionEndDocument(gPrintSession); |
} |
} |
// Only report a printing error once we have completed the print loop. This |
// ensures that every PMBeginXXX call is followed by a matching PMEndXXX |
// call, so the Printing Manager can release all temporary memory and close |
// properly. |
printError = PMSessionError(gPrintSession); |
if (printError != noErr && printError != kPMCancel) { |
PostPrintingErrors(printError); |
} |
} // DoPrintLoop |
/*------------------------------------------------------------------------------ |
Function: |
FlattenAndSavePageFormat |
Parameters: |
pageFormat - a PageFormat object |
Description: |
Flattens a PageFormat object so it can be saved with the document. |
Assumes caller passes a validated PageFormat object. |
------------------------------------------------------------------------------*/ |
OSStatus FlattenAndSavePageFormat(PMPageFormat pageFormat) |
{ |
OSStatus status; |
Handle flatFormatHandle = NULL; |
// Flatten the PageFormat object to memory. |
status = PMFlattenPageFormat(pageFormat, &flatFormatHandle); |
// Write the PageFormat data to file. |
// In this sample code we simply copy it to a global. |
gflatPageFormat = flatFormatHandle; |
return status; |
} // FlattenAndSavePageFormat |
/*------------------------------------------------------------------------------ |
Function: LoadAndUnflattenPageFormat |
Parameters: |
pageFormat - PageFormat object read from document file |
Description: |
Gets flattened PageFormat data from the document and returns a PageFormat |
object. |
The function is not called in this sample code but your application |
will need to retrieve PageFormat data saved with documents. |
------------------------------------------------------------------------------*/ |
OSStatus LoadAndUnflattenPageFormat(PMPageFormat* pageFormat) |
{ |
OSStatus status; |
Handle flatFormatHandle = NULL; |
// Read the PageFormat flattened data from file. |
// In this sample code we simply copy it from a global. |
flatFormatHandle = gflatPageFormat; |
// Convert the PageFormat flattened data into a PageFormat object. |
status = PMUnflattenPageFormat(flatFormatHandle, pageFormat); |
return status; |
} // LoadAndUnflattenPageFormat |
/*------------------------------------------------------------------------------ |
Function: DetermineNumberOfPagesInDoc |
Parameters: |
pageFormat - a PageFormat object addr |
numPages - on return, the size of the document in pages |
Description: |
Calculates the number of pages needed to print the entire document. |
------------------------------------------------------------------------------*/ |
OSStatus DetermineNumberOfPagesInDoc(PMPageFormat pageFormat, UInt32* numPages) |
{ |
OSStatus status; |
PMRect pageRect; |
// PMGetAdjustedPageRect returns the page size taking into account rotation, |
// resolution and scaling settings. |
status = PMGetAdjustedPageRect(pageFormat, &pageRect); |
// In this sample code we simply return a hard coded number. In your application, |
// you will need to figure out how many page rects are needed to image the |
// current document. |
*numPages = 1; |
return status; |
} // DetermineNumberOfPagesinDoc |
/*------------------------------------------------------------------------------ |
Function: PostPrintingErrors |
Parameters: |
status - error code |
Description: |
This is where we could post an alert to report any problem reported |
by the Printing Manager. |
------------------------------------------------------------------------------*/ |
void PostPrintingErrors(OSStatus status) |
{ |
#pragma unused (status) |
} // PostPrintingErrors |
Copyright © 2003 Apple Computer, Inc. All Rights Reserved. Terms of Use | Privacy Policy | Updated: 2003-01-14