pythonmacosquartzcgpdfcontext

Move data between PDFDocument and CGPDFContext?


I want to move data between PDFKit's PDFDocument and Core Graphics's CGPDFContext, but I can't see how to do it. I'm using python, but any code that shows what methods and objects to use would be welcome.
Using CGPDFDocument would be easy, but there are reasons why I need to use PDFDocument instead. You'd think they'd be toll-free bridged.

  1. Creating a context from PDFDocument.

    pdfDoc = PDFDocument.alloc().initWithURL_(pdfURL)
    pdfData = pdfDoc.dataRepresentation()
    CGPDFContextCreate(pdfData, None, metaDict)
    

but I get: 'deflateEnd: error -3: (null).'

  1. I can add a PDFPage to a CGPDFContext with drawWithBox ToContext, but that's only 10.12 and up. I tried this:

    page = pdfDoc.pageAtIndex_(0)
    writeContext = CGPDFContextCreateWithURL(myURL, None, dictarray)
    CGContextBeginPage(writeContext, mbox)
    CGContextDrawPDFPage(writeContext, page.pageRef)
    

This gives me a segmentation fault. (Which is fixed by commenting out the drawPDF line, or replacing page with a CGPDFPage object, instead of a PDFPage.

  1. Initialize a PDFDocument object with Data from the CGPDFContext.

I probably have to use CGDataProviders and Consumers somehow for this, but haven't a clue.


Solution

  • I've taken your code and mixed it with some of the PDF code I've been working on and came up with this that draws a PDF page into a CGContext.

    I'm also using my "Arguments" class which just handles command line options for me. Should be self explanatory.

    I've tested this on a couple of different PDFs and I get a single page in a new PDF.

    #import <Foundation/Foundation.h>
    #import <CoreGraphics/CoreGraphics.h>
    #import <Quartz/Quartz.h>
    
    
    #import "ArgumentsObj.h"
    
    int main (int argc,  char*const* argv)
    {
    
        NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
        Arguments* aa = [Arguments argumentsWithCount:argc values:argv];
        
        if ([aa countPositionalArguments] == 2) {
            NSURL* furl = [NSURL fileURLWithPath:[aa positionalArgumentAt:0]];
            PDFDocument* pdfd = [[PDFDocument alloc] initWithURL:furl];
    
            PDFPage* pp = [pdfd pageAtIndex:0];
            PDFRect mediabox = [pp boundsForBox:kPDFDisplayBoxMediaBox];
    
            NSURL* nsfn = [NSURL fileURLWithPath:[aa positionalArgumentAt:1]];
            NSDictionary* aux = [NSDictionary dictionaryWithObjectsAndKeys:@"main",kCGPDFContextCreator, nil];
    
            CGContextRef cgpdf = CGPDFContextCreateWithURL((CFURLRef)nsfn,&mediabox,(CFDictionaryRef)aux);
        
            CGPDFContextBeginPage(cgpdf, NULL);
    
            CGContextDrawPDFPage(cgpdf, [pp pageRef]);
                           
            CGPDFContextEndPage(cgpdf);
            CGPDFContextClose(cgpdf);
    
        }
        [pool release];
    }