void PDFDocumentImage::setCurrentPage(int page)
{
    if (!m_document)
        return;

    if (page == m_currentPage)
        return;

    if (!(page >= 0 && page < pageCount()))
        return;

    m_currentPage = page;

    CGPDFPageRef cgPage = CGPDFDocumentGetPage(m_document, page + 1);

    // get media box (guaranteed)
    m_mediaBox = CGPDFPageGetBoxRect(cgPage, kCGPDFMediaBox);

    // get crop box (not always there). if not, use media box
    CGRect r = CGPDFPageGetBoxRect(cgPage, kCGPDFCropBox);
    if (!CGRectIsEmpty(r))
        m_cropBox = r;
    else
        m_cropBox = m_mediaBox;

    // get page rotation angle
    m_rotation = CGPDFPageGetRotationAngle(cgPage) * piFloat / 180.0f; // to radians
}
void PDFDocumentImage::draw(GraphicsContext* context, const FloatRect& dstRect, const FloatRect& srcRect, ColorSpace, CompositeOperator op, BlendMode)
{
    if (!m_document || m_currentPage == -1)
        return;

    {
        GraphicsContextStateSaver stateSaver(*context);

        context->setCompositeOperation(op);

        float hScale = dstRect.width() / srcRect.width();
        float vScale = dstRect.height() / srcRect.height();

        // Scale and translate so the document is rendered in the correct location,
        // including accounting for the fact that a GraphicsContext is always flipped
        // and doing appropriate flipping.
        CGContextTranslateCTM(context->platformContext(), dstRect.x() - srcRect.x() * hScale, dstRect.y() - srcRect.y() * vScale);
        CGContextScaleCTM(context->platformContext(), hScale, vScale);
        CGContextScaleCTM(context->platformContext(), 1, -1);
        CGContextTranslateCTM(context->platformContext(), 0, -srcRect.height());
        CGContextClipToRect(context->platformContext(), CGRectIntegral(srcRect));

        // Rotate translate image into position according to doc properties.
        adjustCTM(context);

        CGContextTranslateCTM(context->platformContext(), -m_mediaBox.x(), -m_mediaBox.y());
        CGContextDrawPDFPage(context->platformContext(), CGPDFDocumentGetPage(m_document, m_currentPage + 1));
    }

    if (imageObserver())
        imageObserver()->didDraw(this);
}
Exemple #3
0
bool wxMetaFile::Play(wxDC *dc)
{
    if (!m_refData)
        return false;

    if (!dc->IsOk())
        return false;

    {
        wxDCImpl *impl = dc->GetImpl();
        wxGCDCImpl *gc_impl = wxDynamicCast(impl, wxGCDCImpl);
        if (gc_impl)
        {
            CGContextRef cg = (CGContextRef) (gc_impl->GetGraphicsContext()->GetNativeContext());
            CGPDFDocumentRef doc = M_METAFILEDATA->GetPDFDocument();
            CGPDFPageRef page = CGPDFDocumentGetPage( doc, 1 );
            wxMacCGContextStateSaver save(cg);
            CGContextDrawPDFPage( cg, page );
        }
//        CGContextTranslateCTM( cg, 0, bounds.size.width );
//        CGContextScaleCTM( cg, 1, -1 );
    }

    return true;
}
Exemple #4
0
void PDFDocumentImage::drawPDFPage(GraphicsContext& context)
{
    applyRotationForPainting(context, size(), m_rotationDegrees);

    context.translate(-m_cropBox.x(), -m_cropBox.y());

    // CGPDF pages are indexed from 1.
    CGContextDrawPDFPage(context.platformContext(), CGPDFDocumentGetPage(m_document.get(), 1));
}
Exemple #5
0
void wxMetafileRefData::UpdateDocumentFromData()
{
    wxCFRef<CGDataProviderRef> provider(wxMacCGDataProviderCreateWithCFData(m_data));
    m_pdfDoc.reset(CGPDFDocumentCreateWithProvider(provider));
    if ( m_pdfDoc != NULL )
    {
        CGPDFPageRef page = CGPDFDocumentGetPage( m_pdfDoc, 1 );
        CGRect rect = CGPDFPageGetBoxRect ( page, kCGPDFMediaBox);
        m_width = static_cast<int>(rect.size.width);
        m_height = static_cast<int>(rect.size.height);
    }
}
int main(int argc, char** argv) {
    if (argc <= 1 || !*(argv[1]) || 0 == strcmp(argv[1], "-")) {
        fprintf(stderr, "usage:\n\t%s INPUT_PDF_FILE_PATH [OUTPUT_PNG_PATH]\n", argv[0]);
        return 1;
    }
    const char* output = argc > 2 ? argv[2] : nullptr;
    CGDataProviderRef data = CGDataProviderCreateWithFilename(argv[1]);
    ASSERT(data);
    CGPDFDocumentRef pdf = CGPDFDocumentCreateWithProvider(data);
    CGDataProviderRelease(data);
    ASSERT(pdf);
    CGPDFPageRef page = CGPDFDocumentGetPage(pdf, PAGE);
    ASSERT(page);
    CGRect bounds = CGPDFPageGetBoxRect(page, kCGPDFMediaBox);
    int w = (int)CGRectGetWidth(bounds);
    int h = (int)CGRectGetHeight(bounds);
    CGBitmapInfo info = kCGBitmapByteOrder32Big | kCGImageAlphaPremultipliedLast;
    CGColorSpaceRef cs = CGColorSpaceCreateDeviceRGB();
    ASSERT(cs);
    std::unique_ptr<uint32_t[]> bitmap(new uint32_t[w * h]);
    memset(bitmap.get(), 0xFF, 4 * w * h);
    CGContextRef ctx = CGBitmapContextCreate(bitmap.get(), w, h, 8, w * 4, cs, info);
    ASSERT(ctx);
    CGContextDrawPDFPage(ctx, page);
    CGPDFDocumentRelease(pdf);
    CGImageRef image = CGBitmapContextCreateImage(ctx);
    ASSERT(image);
    CGDataConsumerCallbacks procs;
    procs.putBytes = [](void* f, const void* buf, size_t s) {
        return fwrite(buf, 1, s, (FILE*)f);
    };
    procs.releaseConsumer = [](void* info) {
        fclose((FILE*)info);
    };
    FILE* ofile = (!output || !output[0] || 0 == strcmp(output, "-"))
                  ? stdout : fopen(output, "wb");
    ASSERT(ofile);
    CGDataConsumerRef consumer = CGDataConsumerCreate(ofile, &procs);
    ASSERT(consumer);
    CGImageDestinationRef dst =
        CGImageDestinationCreateWithDataConsumer(consumer, kUTTypePNG, 1, nullptr);
    CFRelease(consumer);
    ASSERT(dst);
    CGImageDestinationAddImage(dst, image, nullptr);
    ASSERT(CGImageDestinationFinalize(dst));
    CFRelease(dst);
    CGImageRelease(image);
    CGColorSpaceRelease(cs);
    CGContextRelease(ctx);
    return 0;
}
bool SkPDFDocumentToBitmap(SkStream* stream, SkBitmap* output) {
    size_t size = stream->getLength();
    void* ptr = sk_malloc_throw(size);
    stream->read(ptr, size);
    CGDataProviderRef data = CGDataProviderCreateWithData(NULL, ptr, size,
                                          CGDataProviderReleaseData_FromMalloc);
    if (NULL == data) {
        return false;
    }

    CGPDFDocumentRef pdf = CGPDFDocumentCreateWithProvider(data);
    CGDataProviderRelease(data);
    if (NULL == pdf) {
        return false;
    }
    SkAutoPDFRelease releaseMe(pdf);

    CGPDFPageRef page = CGPDFDocumentGetPage(pdf, 1);
    if (NULL == page) {
        return false;
    }

    CGRect bounds = CGPDFPageGetBoxRect(page, kCGPDFMediaBox);

    int w = (int)CGRectGetWidth(bounds);
    int h = (int)CGRectGetHeight(bounds);

    SkBitmap bitmap;
    if (!bitmap.allocPixels(SkImageInfo::MakeN32Premul(w, h))) {
        return false;
    }
    bitmap.eraseColor(SK_ColorWHITE);

    size_t bitsPerComponent;
    CGBitmapInfo info;
    getBitmapInfo(bitmap, &bitsPerComponent, &info, NULL);

    CGColorSpaceRef cs = CGColorSpaceCreateDeviceRGB();
    CGContextRef ctx = CGBitmapContextCreate(bitmap.getPixels(), w, h,
                                             bitsPerComponent, bitmap.rowBytes(),
                                             cs, info);
    CGColorSpaceRelease(cs);

    if (ctx) {
        CGContextDrawPDFPage(ctx, page);
        CGContextRelease(ctx);
    }

    output->swap(bitmap);
    return true;
}
void PDFDocumentImage::computeBoundsForCurrentPage()
{
    CGPDFPageRef cgPage = CGPDFDocumentGetPage(m_document.get(), 1);
    CGRect mediaBox = CGPDFPageGetBoxRect(cgPage, kCGPDFMediaBox);

    // Get crop box (not always there). If not, use media box.
    CGRect r = CGPDFPageGetBoxRect(cgPage, kCGPDFCropBox);
    if (!CGRectIsEmpty(r))
        m_cropBox = r;
    else
        m_cropBox = mediaBox;

    m_rotationDegrees = CGPDFPageGetRotationAngle(cgPage);
}
Exemple #9
0
bool SkPDFDocumentToBitmap(SkStream* stream, SkBitmap* output) {
    CGDataProviderRef data = SkCreateDataProviderFromStream(stream);
    if (NULL == data) {
        return false;
    }

    CGPDFDocumentRef pdf = CGPDFDocumentCreateWithProvider(data);
    CGDataProviderRelease(data);
    if (NULL == pdf) {
        return false;
    }
    SkAutoPDFRelease releaseMe(pdf);

    CGPDFPageRef page = CGPDFDocumentGetPage(pdf, 1);
    if (NULL == page) {
        return false;
    }

    CGRect bounds = CGPDFPageGetBoxRect(page, kCGPDFMediaBox);

    int w = (int)CGRectGetWidth(bounds);
    int h = (int)CGRectGetHeight(bounds);

    SkBitmap bitmap;
    if (!bitmap.tryAllocN32Pixels(w, h)) {
        return false;
    }
    bitmap.eraseColor(SK_ColorWHITE);

    size_t bitsPerComponent;
    CGBitmapInfo info;
    getBitmapInfo(bitmap, &bitsPerComponent, &info, NULL);

    CGColorSpaceRef cs = CGColorSpaceCreateDeviceRGB();
    CGContextRef ctx = CGBitmapContextCreate(bitmap.getPixels(), w, h,
                                             bitsPerComponent, bitmap.rowBytes(),
                                             cs, info);
    CGColorSpaceRelease(cs);

    if (ctx) {
        CGContextDrawPDFPage(ctx, page);
        CGContextRelease(ctx);
    }

    output->swap(bitmap);
    return true;
}
Exemple #10
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;
}
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);
}