Rotating an NSView before printing
Rotating an NSView before printing
- Subject: Rotating an NSView before printing
- From: "James Williams" <email@hidden>
- Date: Sat, 28 Apr 2007 09:16:30 -0400
Hello, all! I've worked my way through Hillegass' "Cocoa Programming for Mac OS
X' and I've now started working on my first solo application. Though it's a bit
silly, I'm trying to write a program to create and print envelopes (because it
gives me the chance to work with a subclassed NSView, printing, multiple
windows, and other fun things). Mostly through stubbornness (and with a lot of
help from Google), I've managed to get most of it working. I can draw what I
want on the screen and I can even draw it to the printer.
Unfortunately, when I draw it to the printer, it's oriented wrong. My little
ink jet prints envelopes long ways, so I need to rotate what I'm printing by
90 degrees around the center in a clockwise direction (Address Book does this
if you change the orientation of the printed envelope, if you want to see
what I'm talking about).
I've spent the last two weeks fighting with this and I've almost got it
working, but I'm missing something. I also think I might be making it too
hard so any advice that you have would be really appreciated!
I've simplified my code to just draw a border around the entire envelope. I
think that if I get that working, all of my other code will work as well.
Right now, it prints inverted (correct), but the border for my view is a few
points off of the edge of the page so the entire thing is unable to fit on
the physical envelope (it bleeds off the edge of the right side but is all
white space on the left side).
I hope I haven't included too much introduction or code, but I'm not sure
which of my functions is the problem (maybe all of them are).
Thanks in advance!
--James
In a helper functions file:
float convertInchesToPoints(float inches)
{
return inches * 72.0;
}
In my AppController:
- (IBAction) print:(id)sender
{
NSPrintInfo *printInfo = [NSPrintInfo sharedPrintInfo];
//The envelope is actually 9.5inches wide, but I want it
//to be roated the other way
float paper_height_inches = 9.5;
float paper_width_inches = 4.125;
NSSize paper_size =
NSMakeSize(convertInchesToPoints(paper_width_inches),
convertInchesToPoints(paper_height_inches));
[printInfo setPaperSize: paper_size];
[printInfo setLeftMargin:0.0];
[printInfo setRightMargin:0.0];
[printInfo setBottomMargin:0.0];
[printInfo setTopMargin:0.0];
NSRect viewFrame;
viewFrame.origin = NSMakePoint(0.0,0.0);
viewFrame.size = paper_size;
EnvelopeView *printerView = [[EnvelopeView alloc] initWithFrame:viewFrame];
NSPrintOperation *printOp = [NSPrintOperation
printOperationWithView:printerView printInfo:printInfo];
[printOp setShowPanels:YES];
[printOp runOperation];
[printerView release];
}
In my EnvelopeView (a subclass of NSView):
- (void)drawRect:(NSRect)rect
{
BOOL drawingToScreen = [[NSGraphicsContext currentContext] isDrawingToScreen];
NSRect bounds = [self bounds];
NSRect envelope;
if(!drawingToScreen)
{
envelope.origin = bounds.origin;
envelope.size =
NSMakeSize(convertInchesToPoints(9.5),convertInchesToPoints(4.125));
[NSGraphicsContext saveGraphicsState];
[self rotateViewForPrintingForEnvelope: envelope];
envelope.origin = bounds.origin;
}
else
{
envelope = bounds;
}
[[NSColor whiteColor] set];
[NSBezierPath fillRect:bounds];
[self drawBorderForRect:envelope withPattern:NULL andPatternCount:0
andLineWidth:5.0];
if(!drawingToScreen)
{
[NSGraphicsContext restoreGraphicsState];
}
}
- (void) rotateViewForPrintingForEnvelope: (NSRect) envelope
{
// Cribbed from Gregory Weston
// http://www.cocoabuilder.com/archive/message/cocoa/2007/4/25/182455
NSAffineTransform *transform;
NSPoint centerPoint = [self getCenterPointForRect:envelope];
transform = [NSAffineTransform transform];
[transform translateXBy:centerPoint.x yBy:centerPoint.y];
[transform rotateByDegrees:-90.0];
[transform translateXBy:-(centerPoint.x * 1) yBy:-(centerPoint.y * 1)];
[NSGraphicsContext saveGraphicsState];
[transform concat];
}
- (void) drawBorderForRect: (NSRect) rect withPattern: (const float*)
pattern andPatternCount: (int) count andLineWidth: (float) width
{
NSPoint firstCorner;
NSPoint secondCorner;
NSPoint thirdCorner;
firstCorner.x = rect.origin.x;
firstCorner.y = rect.origin.y + rect.size.height;
secondCorner.x = firstCorner.x + rect.size.width;
secondCorner.y = firstCorner.y;
thirdCorner.x = secondCorner.x;
thirdCorner.y = rect.origin.y;
NSBezierPath *border = [[[NSBezierPath alloc] init] autorelease];
if(pattern != NULL)
{
[border setLineDash:pattern count:count phase:1.0];
}
[border setLineWidth:width];
[border moveToPoint:rect.origin];
[border lineToPoint:firstCorner];
[border lineToPoint:secondCorner];
[border lineToPoint:thirdCorner];
[border lineToPoint:rect.origin];
[border stroke];
}
- (BOOL) knowsPageRange: (NSRange*) rangePtr
{
*rangePtr = NSMakeRange(1,1);
return YES;
}
- (NSRect) rectForPage:(int) pageNum
{
return [self bounds];
}
_______________________________________________
Cocoa-dev mailing list (email@hidden)
Do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden