Why Are Two Pages Printed for this Code?

Discussion in 'Mac Programming' started by kaydell.leavitt, May 3, 2010.

  1. kaydell.leavitt macrumors regular

    Joined:
    Apr 19, 2010
    #1
    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
    
     

    Attached Files:

  2. chown33 macrumors 604

    Joined:
    Aug 9, 2009
    #2
    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.
     
  3. kaydell.leavitt thread starter macrumors regular

    Joined:
    Apr 19, 2010
    #3
    Can You Recommend a Good Example of Printing?

    OK. Can you recommend such an example of printing correctly?
     
  4. chown33 macrumors 604

    Joined:
    Aug 9, 2009
    #4
    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
     
  5. kaydell.leavitt thread starter macrumors regular

    Joined:
    Apr 19, 2010
    #5

    Attached Files:

  6. kaydell.leavitt thread starter macrumors regular

    Joined:
    Apr 19, 2010
    #6
    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?
     
  7. JoshDC macrumors regular

    Joined:
    Apr 8, 2009
    #7
    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
     

Share This Page