NSImageRep mess

I have an NSImage that comes from PDF, so it has one representation of type NSPDFImageRep. I am making the image setDataRetained: YES; to make sure it remains NSPDFImageRep. Later I want to change the page, so I get the rep and set the current page. This is normal.

The problem is when drawing the image, only the first page is rendered.

My impression is that when I draw NSImage, it selects a view and draws that view. Now the image only has one rep, so the one that is being drawn and that is the PDFrep. So why, when I draw the image, isn't the correct page drawing?

HOWEVER, when I draw the view, I get the correct page.

What am I missing?

+2


source to share


2 answers


NSImage caches NSImageRep on first display. In the case of NSPDFImageRep, the "setCacheMode:" message has no effect. This way, the page to be displayed will always be the first page. See this guide for details .

You have two solutions:



  • Direct representation of the drawing.
  • Call the "recache" message on NSImage to force rasterization of the selected page.
+1


source


An alternative mechanism for creating PDF is to use the CGPDF * functions. To do this, use CGPDFDocumentCreateWithURL

to create an object CGPDFDocumentRef

. Then use CGPDFDocumentGetPage

to get the object CGPDFPageRef

. Then you can use CGContextDrawPDFPage

to draw the page in a graphical context.

You may need to apply a transform to ensure that the document is exactly what you want. Use CGAffineTransform

and CGContextConcatCTM

to do so.



Here is some sample code extracted from one of my projects:

// use your own constants here
NSString *path = @"/path/to/my.pdf";
NSUInteger pageNumber = 14;
CGSize size = [self frame].size;

// if we're drawing into an NSView, then we need to get the current graphics context
CGContextRef context = (CGContextRef)([[NSGraphicsContext currentContext] graphicsPort]);

CFURLRef url = CFURLCreateWithFileSystemPath(kCFAllocatorDefault, (CFStringRef)path, kCFURLPOSIXPathStyle, NO);
CGPDFDocumentRef document = CGPDFDocumentCreateWithURL(url);
CGPDFPageRef page = CGPDFDocumentGetPage(document, pageNumber);

// in my case, I wanted the PDF page to fill in the view
// so we apply a scaling transform to fir the page into the view
double ratio = size.width / CGPDFPageGetBoxRect(page, kCGPDFTrimBox).size.width;
CGAffineTransform transform = CGAffineTransformMakeScale(ratio, ratio);
CGContextConcatCTM(context, transform);

// now we draw the PDF into the context
CGContextDrawPDFPage(context, page);

// don't forget memory management!
CGPDFDocumentRelease(document);

      

+1


source







All Articles