void drawWithColorBlendMode(CGContextRef context, CFURLRef url)
{
    // A pleasant green color.
    float green[4] = { 0.584, 0.871, 0.318, 1.0 }; 
    CGRect insetRect, pdfRect;
    
    // Create a CGPDFDocument object from the URL.
    CGPDFDocumentRef pdfDoc = CGPDFDocumentCreateWithURL(url);
    if(pdfDoc == NULL){
		fprintf(stderr, "Couldn't create CGPDFDocument from URL!\n");
		return;
    }
    // Obtain the media box for page 1 of the PDF document.
    pdfRect = CGPDFDocumentGetMediaBox(pdfDoc, 1);
    // Set the origin of the rectangle to (0,0).
    pdfRect.origin.x = pdfRect.origin.y = 0;
    
    // Graphic 1, the left portion of the figure.
    CGContextTranslateCTM(context, 20, 10 + CGRectGetHeight(pdfRect)/2);
    
    // Draw the PDF document.
    CGContextDrawPDFDocument(context, pdfRect, pdfDoc, 1);
    
    // Set the fill color space to that returned by getTheCalibratedRGBColorSpace.
    CGContextSetFillColorSpace(context, getTheCalibratedRGBColorSpace());
    // Set the fill color to green.
    CGContextSetFillColor(context, green);
    
    // Graphic 2, the top-right portion of the figure.
    CGContextTranslateCTM(context, CGRectGetWidth(pdfRect) + 10, 
				    CGRectGetHeight(pdfRect)/2 + 10);

    // Draw the PDF document again.
    CGContextDrawPDFDocument(context, pdfRect, pdfDoc, 1);

    // Make a fill rectangle that is the same size as the PDF document
    // but inset each side by 80 units in x and 20 units in y.
    insetRect = CGRectInset(pdfRect, 80, 20);
    // Fill the rectangle with green. Because the fill color is opaque and
    // the blend mode is Normal, this obscures the drawing underneath. 
    CGContextFillRect(context, insetRect);
    
    // Graphic 3, the bottom-right portion of the figure.
    CGContextTranslateCTM(context, 0, -(10 + CGRectGetHeight(pdfRect)));

    // Draw the PDF document again.
    CGContextDrawPDFDocument(context, pdfRect, pdfDoc, 1);
    
    // Set the blend mode to kCGBlendModeColor which will
    // colorize the destination with subsequent drawing.
    CGContextSetBlendMode(context, kCGBlendModeColor);
    // Draw the rectangle on top of the PDF document. The portion of the
    // background that is covered by the rectangle is colorized
    // with the fill color.
    CGContextFillRect(context, insetRect);

    // Release the CGPDFDocumentRef the code created.
    CGPDFDocumentRelease(pdfDoc);
}
/* For a URL corresponding to an existing PDF document on disk,
create a CGPDFDocumentRef and obtain the media box of the first
page. */
MyPDFData myCreatePDFSourceDocument(CFURLRef url)
{
    MyPDFData myPDFData;
    myPDFData.pdfDoc = CGPDFDocumentCreateWithURL(url);
    if(myPDFData.pdfDoc){
		myPDFData.mediaRect = CGPDFPageGetBoxRect(myPDFData.pdfDoc, kCGPDFMediaBox);
		// Make the media rect origin at 0,0. 
		myPDFData.mediaRect.origin.x = 
		myPDFData.mediaRect.origin.y = 0.;
    }
    return myPDFData;
}
Beispiel #3
0
wxMetafileRefData::wxMetafileRefData( const wxString& filename )
{
    Init();

    if ( !filename.empty() )
    {
        wxCFRef<CFMutableStringRef> cfMutableString(CFStringCreateMutableCopy(NULL, 0, wxCFStringRef(filename)));
        CFStringNormalize(cfMutableString,kCFStringNormalizationFormD);
        wxCFRef<CFURLRef> url(CFURLCreateWithFileSystemPath(kCFAllocatorDefault, cfMutableString , kCFURLPOSIXPathStyle, false));
        m_pdfDoc.reset(CGPDFDocumentCreateWithURL(url));
    }
}
Beispiel #4
0
int generatePages(const char *documentPath) {
	int error = 0;
	CFStringRef path = CFStringCreateWithCString(
		NULL, documentPath, kCFStringEncodingUTF8
	);
	CFURLRef url = CFURLCreateWithFileSystemPath(
		NULL, path, kCFURLPOSIXPathStyle, 0
	);
	CGPDFDocumentRef document = CGPDFDocumentCreateWithURL(url);

	if (document != NULL) {
		size_t lastPageIndex = CGPDFDocumentGetNumberOfPages(document) + 1;
		CFStringRef pdfPath = CFSTR("document.pdf");
		CFURLRef pdfUrl = CFURLCreateWithFileSystemPath(
			NULL, pdfPath, kCFURLPOSIXPathStyle, 0
		);
		CGContextRef context = CGPDFContextCreateWithURL(pdfUrl, NULL, NULL);

		printf("Compressing PDF\n");
		for(size_t pageIndex = 1; pageIndex < lastPageIndex; ++pageIndex) {
			CGPDFPageRef page = CGPDFDocumentGetPage(document, pageIndex);
			const CGRect cropBox = CGPDFPageGetBoxRect(page, kCGPDFCropBox);

			printf("Adding page %lu\n", pageIndex);
			CGContextBeginPage(context, &cropBox);
			CGContextDrawPDFPage(context, page);
			CGContextEndPage(context);
		}

		CGContextRelease(context);
		if (pdfUrl != NULL) CFRelease(pdfUrl);
		if (pdfPath != NULL) CFRelease(pdfPath);
		CGPDFDocumentRelease(document);
	} else {
		fprintf(stderr, "Cannot open PDF document\n");
		error = 1;
	}

	if(url != NULL) CFRelease(url);
	if(path != NULL) CFRelease(path);

	return error;
}
CGPDFDocumentRef getThePDFDoc(CFURLRef url, float *w, float *h)
/*
    This function caches a CGPDFDocumentRef for
    the most recently requested PDF document.
*/
{
    static CGPDFDocumentRef pdfDoc = NULL;
    static CFURLRef pdfURL = NULL;
    static float width = 0, height = 0;
    
    if(url == NULL)
		return;
    
    // See whether to update the cached PDF document.
    if(pdfDoc == NULL || url != pdfURL){ 
		// Release any cached document or URL.
		if (pdfDoc) CGPDFDocumentRelease(pdfDoc);
		if (pdfURL) CFRelease(pdfURL);
		
		pdfDoc = CGPDFDocumentCreateWithURL(url);
		if(pdfDoc != NULL){
			CGRect pdfMediaRect = CGPDFDocumentGetMediaBox(pdfDoc, 1);
			width = pdfMediaRect.size.width;
			height = pdfMediaRect.size.height;
			// Retain the URL of the PDF file being cached.
			pdfURL = CFRetain(url);
		}else{
			pdfURL = NULL;
		}
    }
    
    if(pdfDoc){
		// Let the caller know the width and height of the document.
		*w = width;
		*h = height;
    }
    
    return pdfDoc;
}
void dumpPageStreams(CFURLRef url, FILE *outFile)
{
    CGPDFDocumentRef pdfDoc = NULL;
    CGPDFOperatorTableRef table = NULL;
    MyDataScan myData;
    size_t totalImages, totPages, i;

    // Create a CGPDFDocumentRef from the input PDF file.
    pdfDoc = CGPDFDocumentCreateWithURL(url);
    if(!pdfDoc){
		fprintf(stderr, "Couldn't open PDF document!\n"); return;
    }
    // Create the operator table with the needed callbacks.
    table = createMyOperatorTable();
    if(!table){
		CGPDFDocumentRelease(pdfDoc);
		fprintf(stderr, "Couldn't create operator table\n!"); return;
    }
    // Initialize the count of the images.
    totalImages = 0;

    // Obtain the total number of pages for the document.
    totPages = CGPDFDocumentGetNumberOfPages(pdfDoc);

    // Loop over all the pages in the document, scanning the
    // content stream of each one.
    for(i = 1; i <= totPages; i++){
		CGPDFScannerRef scanner = NULL;
		// Get the PDF page for this page in the document.
		CGPDFPageRef p = CGPDFDocumentGetPage(pdfDoc, i);
		// Create a reference to the content stream for this page.
		CGPDFContentStreamRef cs = CGPDFContentStreamCreateWithPage(p);
		if(!cs){
			CGPDFOperatorTableRelease(table);
			CGPDFDocumentRelease(pdfDoc);
			fprintf(stderr, 
			"Couldn't create content stream for page #%zd!\n", i);
			return;
		}
		// Create a scanner for this PDF document page.
		scanner = CGPDFScannerCreate(cs, table, &myData);
		if(!scanner){
			CGPDFContentStreamRelease(cs);
			CGPDFOperatorTableRelease(table);
			CGPDFDocumentRelease(pdfDoc);
			fprintf(stderr, "Couldn't create scanner for page #%zd!\n", i);
			return;
		}
		// Initialize the counters of images for this page.
		myData.numImagesWithColorThisPage = 0;
		myData.numImageMasksThisPage =  0;
		myData.numImagesMaskedWithMaskThisPage =  0;
		myData.numImagesMaskedWithColorsThisPage = 0;
	
		/* 	CGPDFScannerScan causes Quartz to scan the content stream,
			calling the callbacks in the table when the corresponding
			operator is encountered. Once the content stream for the
			page has been consumed or Quartz detects a malformed 
			content stream, CGPDFScannerScan returns. 
		*/
		if(!CGPDFScannerScan(scanner)){
			fprintf(stderr, "Scanner couldn't scan all of page #%zd!\n", i);
		}
		// Print the results for this page.
		printPageResults(outFile, myData, i);
		
		// Update the total count of images with the count of the
		// images on this page.
		totalImages += 
			myData.numImagesWithColorThisPage + 
			myData.numImageMasksThisPage +
			myData.numImagesMaskedWithMaskThisPage +
			myData.numImagesMaskedWithColorsThisPage;
	
		// Once the page has been scanned, release the 
		// scanner for this page.
		CGPDFScannerRelease(scanner);
		// Release the content stream for this page.
		CGPDFContentStreamRelease(cs);
		// Done with this page; loop to next page.
    }
    printDocResults(outFile, totPages, totalImages);

    // Release the operator table this code created.
    CGPDFOperatorTableRelease(table);
    // Release the input PDF CGPDFDocumentRef.
    CGPDFDocumentRelease(pdfDoc);
}