If I use -[NSView dataWithPDFInsideRect:]
to create a PDF from an NSTextView
, I get a single-page PDF with stuff past the bottom cut off. What do I need to do to get pagination to happen? Would embedding the NSTextView
in an NSScrollView
help?
How to create paginated PDF from NSTextView?
I tried this
NSMutableData* pdfData = [[NSMutableData alloc] init];
NSPrintOperation* printOp = [NSPrintOperation
PDFOperationWithView: textView
insideRect: pageBounds
toData: pdfData
printInfo: NSPrintInfo.sharedPrintInfo];
[printOp runOperation];
and it still creates only one page.
I also tried making a subclass of NSTextView
that overrides rectForPage:
and knowsPageRange:
, but those methods never got called.
Creating a PDF with multiple pages isn't easy. You are going to have use Quartz (CoreGraphics). Create a PDF context. Do the following until you reach the end of the text:
- Determine how much text can fit on a page.
- Call the PDF context's
beginPage
function. - Draw the page of text.
- Call the PDF context's
endPage
function. - Update the location in the text to start drawing the next page.
The following article explains what you have to do to create a multiple page PDF with Quartz and Core Text:
https://www.meandmark.com/blog/2016/08/creating-pdfs-with-core-text-and-quartz/
The TPPDF Swift package can be used to create PDF files. You will probably find it easier to use than to create a PDF with Quartz.
Thanks for writing, and I don’t doubt that your approach would work, but I don’t get why creating PDF should be fundamentally harder than any other multi page print job, since it’s just a special case.
By the way, I tried making a non-PDF NSPrintOperation
, and that produced multiple pages that were all blank. Apple’s docs gave me the impression that it shouldn’t be so hard to print a view.
I came up with yet another approach: I inserted the text view in an NSClipView
, which I inserted in a printing-aware container view, and then printed to a temporary PDF file, like this:
NSPrintInfo* printInfo = [[NSPrintInfo alloc] init];
printInfo.paperSize = pageBounds.size;
printInfo.topMargin = 0.0;
printInfo.bottomMargin = 0.0;
printInfo.leftMargin = 0.0;
printInfo.rightMargin = 0.0;
printInfo.horizontallyCentered = NO;
printInfo.verticallyCentered = NO;
printInfo.verticalPagination = NSPrintingPaginationModeAutomatic;
printInfo.horizontalPagination = NSPrintingPaginationModeClip;
printInfo.jobDisposition = NSPrintSaveJob;
printInfo.dictionary[NSPrintJobSavingURL] = tempPDFURL;
NSPrintOperation* printOp = [NSPrintOperation
printOperationWithView: container
printInfo: printInfo];
printOp.showsProgressPanel = NO;
printOp.showsPrintPanel = NO;
[printOp runOperation];
It works, except for one thing. My text contains some link attributes. When creating PDF using the PDF-specific methods like dataWithPDFInsideRect:
, those links turn into PDF annotations. When printing this way, the links just go away. Aargh.