Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

kaydell.leavitt

macrumors regular
Original poster
Apr 19, 2010
100
0
I'm printing an invoice with the following code.

The print job is created, but two pages print and things don't print where I expect them to print. I expect the title of the document to be "INVOICE" and to print at the top, centered horizontally, but it doesn't print there at all on the first page and it prints with the wrong centering on the second page.

What am I doing wrong?

Code:
//
//  InvoiceView.m
//  PrintTest
//
//  Created by kaydell on 4/30/10.
//  Copyright 2010 LevSolve.com. All rights reserved.
//

#import "InvoiceView.h"
#import "InvoiceDocument.h"

@interface TitleView : NSView {
	NSString *title;
}
@end

@implementation InvoiceView

@synthesize document;
@synthesize logoView;
@synthesize paperSize;
@synthesize leftMargin;
@synthesize rightMargin;
@synthesize topMargin;
@synthesize bottomMargin;

- (id) initWithInvoiceDocument:(InvoiceDocument *)invDoc {
	if (self = [super init]) {
		
		// store a reference to the invoice doument
		self.document = invDoc;
		
		NSPrintInfo *printInfo = [NSPrintInfo sharedPrintInfo];
		NSLog(@"%@",printInfo);
		paperSize = printInfo.paperSize;
		leftMargin = [printInfo leftMargin];
		rightMargin = [printInfo rightMargin];
		topMargin = [printInfo topMargin];
		bottomMargin = [printInfo bottomMargin];
		
		// make the frame non-empty or it won't print
		NSRect rect = NSMakeRect(0.0, 0.0, paperSize.width-1, paperSize.height-1); // make frame rect non-empty
		[self setFrame: rect];
		
		// create a LogoView object to print a logo (if any)
		self.logoView = [[LogoView alloc] init];
		
	}
	return self;
}

- (void)drawString:(NSString *)string centeredInRect:(NSRect)r withAttributes:(NSDictionary *)theAttribute
{
	NSPoint stringOrigin;
	NSSize stringSize;
	
	stringSize = [string sizeWithAttributes:theAttribute];
	stringOrigin.x = r.origin.x + (r.size.width - stringSize.width)/2;
	stringOrigin.y = r.origin.y  + (r.size.height - stringSize.height)/2;
	[string drawAtPoint:stringOrigin withAttributes:theAttribute];
}

- (void)drawString:(NSString *)string rightJustifiedInRect:(NSRect)r withAttributes:(NSDictionary *)theAttribute
{
	NSPoint stringOrigin;
	NSSize stringSize;
	
	stringSize = [string sizeWithAttributes:theAttribute];
	stringOrigin.x = r.origin.x + (r.size.width - stringSize.width);
	stringOrigin.y = r.origin.y;
	[string drawAtPoint:stringOrigin withAttributes:theAttribute];
}

- (void) drawRect:(NSRect)dirtyRect { // <<<< This method is called twice, once for each page, but why are there two pages?
	
	// write the fields of the invoice document out to the console (for debugging)
	[document log];
	
	// draw the title
	NSRect r = NSMakeRect(leftMargin,topMargin,paperSize.width,12);
	[self drawString:document.title centeredInRect:r withAttributes:nil];
	
	// draw the logo	
	[logoView drawRect:dirtyRect];
}

- (void) print:(id)sender {
	
	// create a print operation object
	NSPrintOperation *printOperation = [NSPrintOperation printOperationWithView:self];
	
	// do the print job
	[printOperation runOperation];
	
}

- (void) dealloc {
	[logoView release];
	[super dealloc];
}

@end
 

Attachments

  • Screen.png
    Screen.png
    71.8 KB · Views: 127
I'm pretty sure margins are insets from each edge of the paper size. Your calculation of the rect in which to center your text is treating leftMargin as if it lies outside the paper size.

Take a piece of paper and draw a vertical line inset one inch from left edge. The margin is within the paper size, not outside it.

And I think you're getting two pages because when you treat margins as if they're outside the paper size, you end up with an area that spans two pages. That is, margin + paper size is larger than paper size, so it's impossible to fit that on one page.

It looks like you're guessing at how things work. If you're not working from a known-working example of printing, you probably should be.
 
Can You Recommend a Good Example of Printing?

If you're not working from a known-working example of printing, you probably should be.

OK. Can you recommend such an example of printing correctly?
 
What have you tried?

I don't have a specific example at hand. It doesn't seem difficult to find some, though.

First, I see a lot of apparently relevant articles when googling:
mac os x cocoa print example

Next, I went to the NSPrintInfo class reference page (i.e. the class you used in your posted code):
http://developer.apple.com/mac/libr...es/NSPrintInfo_Class/Reference/Reference.html

and there are five "Related sample code" items listed:
ImageApp
Quartz Composer WWDC 2005 TextEdit
QuickLookSketch
Sketch+Accessibility
Sketch-112
 

Attachments

  • Screen shot 2010-05-04 at 1.35.08 AM.png
    Screen shot 2010-05-04 at 1.35.08 AM.png
    136.8 KB · Views: 100
I'm trying to flip the y-coordinate myself with the code below:

Code:
- (BOOL)isFlipped
{
	return NO;
}

- (CGFloat) flip:(CGFloat)y1 {
	CGFloat diff = (midPoint-y1);
	CGFloat y2 = (midPoint+diff);
	return y2;
}

This seems like a lot of work. Is there an easier way than identifying all of my y-coordinates and calling the flip method on all of them?

The code above *does* print the logo the right way, but other things are messed up. Is there an easier way?
 
Using 10.6? There was quirky behaviour with NSImage in previous versions (I think this is what you're seeing) so an extra method was added. Try using

Code:
drawInRect:fromRect:operation:fraction:respectFlipped:hints:

with different values for respectFlipped:

See this article for more information (section "NSImage: deprecating -[NSImage setFlipped:], adding a drawing method…"):
http://developer.apple.com/mac/library/releasenotes/cocoa/AppKit.html
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.