Skip navigation.
 
mlScaled Printing
FROM : John Nairn
DATE : Mon Jun 30 23:44:59 2008

I cannot find any mention of what a view needs to do to support scaled 
printing, so I thought it would be automatic as long as I adjust 
things for the current scaling. Unfortunately, the view always prints 
at 100% despite changing the scale setting in a page layout dialog.

Below is all the code I added for printing a flipped view that may 
span multiple pages. The view has a bunch of framed subviews, each 
containing some text and soon graphics, that are connected by lines (a 
family tree).

The controller first sets the margins to the printable area (to 
minimize number of pages needed) and then starts printing of the view 
with

- (void)printChartView:(id)pview
{
   NSPrintInfo *pi = [[self document] printInfo];
   NSPrintOperation *printOp = [NSPrintOperation 
printOperationWithView:pview printInfo:pi];
   [printOp setShowPanels:YES];
   [printOp runOperation];
}

The printing uses custom pagination (following Apple's example, but in 
both directions instead of just vertical direction) and accounts for 
scaling in the calculations. The knowsPageRange and rectForPage are 
returning appropriate results for any scale setting, but the view 
always prints at 100% and thus scaling does not print correctly (an 
aside: at first I thought I should not even need knowsPageRange and 
rectForPage and could use auto pagination instead; although it worked, 
it did not use the margins I set up before printing and therefore used 
less of each page). This view's drawRect method has nothing special 
for printing (except to not highlight the currently selected subview).

// Return the number of pages available for printing
- (BOOL)knowsPageRange:(NSRangePointer)range
{
   NSRect bounds = [self bounds];
   NSSize printSize = [self calculatePrintSize];

   range->location = 1;
   int horiz = NSWidth(bounds)/printSize.width + 1;
   int vert = NSHeight(bounds)/printSize.height + 1;
   range->length = horiz*vert;
   return YES;
}

// Return the drawing rectangle for a particular page number
- (NSRect)rectForPage:(int)page
{
   NSRect bounds = [self bounds];
   NSSize printSize = [self calculatePrintSize];

   // hpage 1 to horiz and vpage 1 to vert (horiz and vert defined above)
   int pagesForWidth = NSWidth(bounds)/printSize.width + 1;
   int vpage = page/pagesForWidth;
   int hpage = page % pagesForWidth;
   if(hpage == 0)
       hpage = pagesForWidth;
   else
       vpage++;
   return NSMakeRect(NSMinX(bounds)+(hpage-1)*printSize.width,
                       NSMinY(bounds)+(vpage-1)*printSize.height,
                       printSize.width,printSize.height);
}

// Calculate the size of the view that fits on a single page
- (NSSize)calculatePrintSize
{
   // Obtain the print info object for the current operation
   NSPrintInfo *pi = [[NSPrintOperation currentOperation] printInfo];

   // Calculate the page size in points
   NSSize paperSize = [pi paperSize];
   float pageHeight = paperSize.height - [pi topMargin] - [pi 
bottomMargin];
   float pageWidth = paperSize.width - [pi leftMargin] - [pi rightMargin];

   // Convert size to the scaled view
   float scale = [[[pi dictionary] objectForKey:NSPrintScalingFactor] 
floatValue];
   return NSMakeSize(pageWidth/scale, pageHeight/scale);
}

---------------
John Nairn (1-541-737-4265, FAX:1-541-737-3385)
Professor and Richardson Chair
Web Page: http://woodscience.oregonstate.edu/faculty/Nairn
FEA/MPM Web Page: http://oregonstate.edu/~nairnj

Related mailsAuthorDate
mlScaled Printing John Nairn Jun 30, 23:44
mlRe: Scaled Printing Scott Ribe Jul 1, 19:29
mlRe: Scaled Printing John Nairn Jul 1, 22:53
mlRe: Scaled Printing Scott Ribe Jul 1, 23:41