I have a cocoa app I'm working on in which I created a customView that I want to send to the printer. In the subclassed NSView, I set some frame options as well, the code is below. I have 2 global variables to hold printing information declared outside main() function.
- (id)initWithFrame:(NSRect)frame
{
extern NSPrintInfo *globalPrintInfo;
extern NSPrintOperation *globalPrintOperation;
//Modify the frame before it's sent to it's super method. Also set the global variables to there default values.
globalPrintOperation = [NSPrintOperation printOperationWithView:self];
globalPrintInfo = [globalPrintOperation printInfo];//Get the print information from it.
[globalPrintInfo setBottomMargin:0.0];
[globalPrintInfo setLeftMargin:0.0];
[globalPrintInfo setTopMargin:0.0];
[globalPrintInfo setRightMargin:0.0];
[globalPrintOperation setPrintInfo:globalPrintInfo];//save the printInfo changes.
//modify the frame to reflect the correct height & width of the paper.
frame.size.height = globalPrintInfo.paperSize.height-globalPrintInfo.topMargin-globalPrintInfo.bottomMargin;
frame.size.width = globalPrintInfo.paperSize.width-globalPrintInfo.leftMargin-globalPrintInfo.rightMargin;
frame.origin.x=0;
frame.origin.y=0;
NSLog(@"Printer Name=%@, Printer Type=%@",globalPrintInfo.printer.name,globalPrintInfo.printer.type);
self = [super initWithFrame:frame];
if (self) {
// Initialization code here.
}
return self;
}
For the subclassed NSView so that I can see it's boundaries I added the following code below to it's drawRect method.
- (void)drawRect:(NSRect)dirtyRect
{
if ( [NSGraphicsContext currentContextDrawingToScreen] ) {
NSLog(@"Drawing To Screen");
} else {
NSLog(@"Drawing To Printer");
}
// Draw common elements here
CGContextRef myContext = [[NSGraphicsContext currentContext] graphicsPort];
//Set color of drawing to green, and fill the rectangle green, so we can see it's boundaries.
[[NSColor greenColor] setFill];
NSRectFill(dirtyRect);
CGContextSelectFont(myContext, "Helvetica-Bold", 18, kCGEncodingMacRoman);
CGContextSetCharacterSpacing(myContext, 10);
CGContextSetTextDrawingMode(myContext, kCGTextFillStroke);
CGContextSetRGBFillColor(myContext, 0, 0, 0, 1);//black
CGContextSetRGBStrokeColor (myContext, 0, 0, 1, 1);//blue stroke
CGContextShowTextAtPoint(myContext, 40, 0, "Here is some text!", 18);
}
When I go to run the print operation using the global variable, like so...
- (IBAction)print:(id)sender {
NSLog(@"Testing Print");
extern NSPrintOperation *globalPrintOperation;
[globalPrintOperation runOperation];
}
I get the print window to appear and I see my 'green background' for my view, but for some reason it's split onto 2 pages. I'm not sure exactly what is going on as I set the width and height of the frame to the pagesize.width & height, any help is appreciated. Some images of what I see are below.
My guess is the pagesize width and height are in different units than the pixels unit type used for defining the frame of the view.
My ultimate goal is to make a program where the user selects what they want and it prints particular pages based on the options they selected, but first I got to figure out how to even get what 'content' I expect onto '1' page instead of '2'. I could manually figure out the width and height by experimentation but that would not be very dynamic for different paper sizes I'm assuming.
Thanks in advance.
EDIT ***
I just edited my code to the following below for the subclassed NSVIEW
//METHOD OVERIDES
- (id)initWithFrame:(NSRect)frame
{
extern NSPrintInfo *globalPrintInfo;
extern NSPrintOperation *globalPrintOperation;
//Modify the frame before it's sent to it's super method. Also set the global variables to there default values.
globalPrintOperation = [NSPrintOperation printOperationWithView:self];//use whatever is currently there as the default print operation.
globalPrintInfo = [globalPrintOperation printInfo];//Get the print information from it.
[globalPrintInfo setBottomMargin:0.0];
[globalPrintInfo setLeftMargin:0.0];
[globalPrintInfo setTopMargin:0.0];
[globalPrintInfo setRightMargin:0.0];
[globalPrintOperation setPrintInfo:globalPrintInfo];//save the printInfo changes.
//modify the frame to reflect the correct height & width of the paper.
frame.size.height = (globalPrintInfo.paperSize.height-globalPrintInfo.topMargin-globalPrintInfo.bottomMargin);
frame.size.width = globalPrintInfo.paperSize.width-globalPrintInfo.leftMargin-globalPrintInfo.rightMargin;
frame.origin.x=0;
frame.origin.y=0;
NSLog(@"Printer Name=%@, Printer Type=%@",globalPrintInfo.printer.name,globalPrintInfo.printer.type);
self = [super initWithFrame:frame];
if (self) {
// Initialization code here.
}
return self;
}
- (void)drawRect:(NSRect)dirtyRect
{
if ( [NSGraphicsContext currentContextDrawingToScreen] ) {
NSLog(@"Drawing To Screen");
} else {
NSLog(@"Drawing To Printer");
}
// Draw common elements here
CGContextRef myContext = [[NSGraphicsContext currentContext] graphicsPort];
//Set color of drawing to green, and fill the rectangle green, so we can see it's boundaries.
[[NSColor greenColor] setFill];
NSRectFill(dirtyRect);
CGContextSelectFont(myContext, "Helvetica-Bold", 18, kCGEncodingMacRoman);
CGContextSetCharacterSpacing(myContext, 10);
CGContextSetTextDrawingMode(myContext, kCGTextFillStroke);
CGContextSetRGBFillColor(myContext, 0, 0, 0, 1);//black
CGContextSetRGBStrokeColor (myContext, 0, 0, 1, 1);//blue stroke
CGContextShowTextAtPoint(myContext, 40, 0, "Here is some text!", 18);
}
- (BOOL)knowsPageRange:(NSRangePointer)range {
NSRect bounds = [self bounds];
float printHeight = [self calculatePrintHeight];
range->location = 1;
range->length = NSHeight(bounds) / printHeight + 1;
NSLog(@"Calculated Page Range");
return YES;
}
// Return the drawing rectangle for a particular page number
- (NSRect)rectForPage:(int)page {
NSRect bounds = [self bounds];
float pageHeight = [self calculatePrintHeight];
NSLog(@"Created Rect For View");
return NSMakeRect( NSMinX(bounds), NSMaxY(bounds) - page * pageHeight,
NSWidth(bounds), pageHeight );
}
//CUSTOM METHODS
// Calculate the vertical size of the view that fits on a single page
- (float)calculatePrintHeight {
extern NSPrintInfo *globalPrintInfo;
extern NSPrintOperation *globalPrintOperation;
// Obtain the print info object for the current operation
// Calculate the page height in points
NSSize paperSize = [globalPrintInfo paperSize];
float pageHeight = paperSize.height - [globalPrintInfo topMargin] - [globalPrintInfo bottomMargin];
// Convert height to the scaled view
float scale = [[[globalPrintInfo dictionary] objectForKey:NSPrintScalingFactor]
floatValue];
NSLog(@"Calculated Print Height:%f",(pageHeight/scale));
return (pageHeight / scale);
}
@end
I was able to get what I want now, accept when I go to print preview it still thinks there is a second page for some reason? not sure why about that now. I'll upload what I see...
Notice how it says 1 of 2? 2nd page is just blank white though.