Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the relationship between CGPDFContext and CGPDFDocument?

My understanding of this was that perhaps CGPDFContext is to be used for editing PDF document data and CGPDFDocument is used for storing it, since the documentation doesn't list any ways to alter the content of a CGPDFDocument.

I'm also not quite sure what CGDataConsumer/Provider does. From reading the documentation I got the impression that the consumer/provider abstracts the relationship between the CG object and the CFData it writes to; so I don't have to do that myself. So I figured the following code would create a two page blank PDFdocument:

//Don't know exactly how large a PDF is so I gave it 1 MB for now
self->pdfData = CFDataCreateMutable(kCFAllocatorDefault, 1024);

self->consumerRef = CGDataConsumerCreateWithCFData(self->pdfData);

self.pdfRef = CGPDFContextCreate(self->consumerRef, NULL, NULL);
CGPDFContextBeginPage(self.pdfRef, NULL); //Creates a blank page?
CGPDFContextEndPage(self.pdfRef);
CGPDFContextBeginPage(self.pdfRef, NULL); //Creates a second blank page?
CGPDFContextEndPage(self.pdfRef);

//Copies the data from pdfRef's consumer into docRef's provider?
self.docRef = CGPDFDocumentCreateWithProvider( 
CGDataProviderCreateWithCFData(
CFDataCreateCopy(kCFAllocatorDefault, self->pdfData)
));

It didn't work though, and NSLogging the first two pages of docRef returns NULL. I'm rather new at this, the C-Layer stuff in particular. Can someone explain to me the relationship between CGPDFContext, CGPDFDocument, CGDataConsumer & CGDataProvider and how I'd use them to create a blank PDF?

like image 443
PopKernel Avatar asked Jan 26 '26 14:01

PopKernel


1 Answers

Your basic understanding is correct as far as I can see:

  • A CGPDFContext is a drawing context that "translates" everything that is drawn onto it to PDF instructions (typically for storage in a PDF file).
  • A CGPDFDocument is used to open an existing PDF file and get information from it.

When you want to create your own PDF file, you have two ways to do it as described here: https://developer.apple.com/library/mac/documentation/graphicsimaging/reference/CGPDFContext/Reference/reference.html

  1. Use "CGPDFContextCreate" which you pass a data consumer. The data consumer gets the data and can do with it as it pleases (you could create a data consumer that passes the PDF onto the clipboard for example).
  2. Use "CGPDFContextCreateWithURL" which you pass a URL. In that case your data will be written to a PDF file at that URL.

If you want to use these functions, have a look at this page https://developer.apple.com/library/mac/documentation/graphicsimaging/Conceptual/drawingwithquartz2d/dq_pdf/dq_pdf.html#//apple_ref/doc/uid/TP30001066-CH214-TPXREF101 which explains in detail how to create PDF files with a data provider and without (simply to a PDF).

To figure out what is happening I would start by trying to write a simple PDF file to disk before writing one to a data provider and then using that data provider immediately to read it again. Without trying your code however, let me point out that you didn't use "CGPDFContextClose" which is described in the document as closing the PDF document and flushing all information to output. You could actually having a situation where stuff is cached and not written to your data provider yet, simply because you haven't forced that.

like image 99
David van Driessche Avatar answered Jan 28 '26 08:01

David van Driessche



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!