Draw over a PDF background?

Discussion in 'iOS Programming' started by csnplt, Feb 3, 2010.

  1. csnplt macrumors 6502

    csnplt

    Joined:
    Aug 29, 2008
    Location:
    Chicago Area
    #1
    I have an app that displays multipage PDF files, allowing scrolling through all of the pages, and I would like to add the ability for users to write comments over top of the original PDF by moving their fingers over the screen (this is best on the iPad, with its bigger screen).

    I'm trying to think of a way to do this. I want to save the edited PDF file as a new PDF file, so that I can reload it in the future and have all of the comments still intact. I would also like the app to work in landscape or portrait mode, so I'd like something that could scale.

    I'm still in the process of thinking through this problem, and I need an idea for where to start. Does anyone have any experience with something like this?

    Thanks a lot!
     
  2. North Bronson macrumors 6502

    Joined:
    Oct 31, 2007
    Location:
    San José
    #2
    For the 3.1.X OS, you will probably be drawing the PDF to a Quartz graphics context. You can then draw arbitrary paths over that graphics context. Take a look at the Quartz 2D Programming Guide in the Apple documentation for more ideas.

    You might also handle the drawing with OpenGL.
     
  3. csnplt thread starter macrumors 6502

    csnplt

    Joined:
    Aug 29, 2008
    Location:
    Chicago Area
    #3
    Thanks. Do you have any experience drawing to a PDF Context? I've been experimenting a bit and can't get much to work. Here's some code that I'm using, trying to draw a black rectangle to test this out, but I only get a blank pdf.

    I've taken this from the sample docs that you told me about.

    Code:
    CGContextRef createPDFContext (const CGRect *inMediaBox, CFStringRef path)
    {
        CGContextRef myOutContext = NULL;
        CFURLRef url;
        CGDataConsumerRef dataConsumer;
    	
        url = CFURLCreateWithFileSystemPath (NULL,  path, kCFURLPOSIXPathStyle, false);
    
        if (url != NULL)
        {
            dataConsumer = CGDataConsumerCreateWithURL (url);
            if (dataConsumer != NULL)
            {
                myOutContext = CGPDFContextCreate (dataConsumer, inMediaBox, NULL);
                CGDataConsumerRelease (dataConsumer);
            }
            CFRelease(url);
        }
        return myOutContext;
    }
    
    -(void)writeTestPDFtoFile:(NSString*)whereToStorePDF
    {
    	int height = 200;
    	int width = 200;
    	
    	const CGRect box = CGRectMake(0,0,width,height);
    	
    	CFStringRef path = whereToStorePDF;
    	
    	CGContextRef pdfContext = createPDFContext(&box, path);
    	if(!pdfContext)
    	{
    		fprintf(stderr, "couldn't create PDF Context!");
    		return;
    	}
    	
    	CGContextBeginPage(pdfContext, &box);
    	
    	CGContextSetFillColor(pdfContext, [UIColor blackColor]);
    	CGContextFillRect(pdfContext, CGRectMake(10, 10, 100, 100));
    	
    	CGContextEndPage(pdfContext);
    	CGContextRelease(pdfContext);
    }
    
    Is there something I'm doing wrong?
     
  4. North Bronson macrumors 6502

    Joined:
    Oct 31, 2007
    Location:
    San José
    #4
    I'm not sure if UIColors are toll-free bridged with CGColors. Have you tried switching:

    Code:
    CGContextSetFillColor(pdfContext, [UIColor blackColor]);
    with:

    Code:
    CGContextSetFillColor(pdfContext, [[UIColor blackColor] CGColor]);
     
  5. csnplt thread starter macrumors 6502

    csnplt

    Joined:
    Aug 29, 2008
    Location:
    Chicago Area
    #5
    Thanks, I should have seen that!

    I have one more question. I'm trying to make a copy of the original PDF, with all of the content from all pages stuck onto one page. That way, users will easily be able to draw between "pages" if they need to. I could also simulate different pages by drawing a grey rectangle between them if need be.

    I've gotten most of this to work, except all of the text in the PDF's that I've tried becomes garbled. I've attached two screenshots as an example. One is from the original and the other is from the output PDF.

    Here's the code I'm using:

    Code:
    -(void)concatenatePagesOfPDFtoFile:(NSString*)whereToStorePDF
    {
    	//Get number of pages
    	NSURL *pdfURL = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"test2" ofType:@"pdf"]];
    	CGPDFDocumentRef pdf = CGPDFDocumentCreateWithURL((CFURLRef)pdfURL);
    	int pageNumbers = CGPDFDocumentGetNumberOfPages(pdf);
    	
    	int height;
    	int width;
    	
    	//Get max page size, in case one is larger than another:
    	for(int i=0; i<pageNumbers; i++)
    	{
    		CGPDFPageRef currentPDFPage = CGPDFDocumentGetPage(pdf, i+1);
    		CGRect pageMediaBox = CGPDFPageGetBoxRect(currentPDFPage, kCGPDFMediaBox);
    		
    		height = pageMediaBox.size.height * pageNumbers;
    		width = pageMediaBox.size.width;
    	}
    	
    	CGPDFDocumentRelease(pdf);
    	
    
    	const CGRect box = CGRectMake(0,0,width,height); //Use as the default page size
    	
    	CGContextRef pdfContext = createPDFContext(&box, whereToStorePDF);
    	if(!pdfContext)
    		NSLog(@"Unable to create PDF Context");
    	
    	CGContextBeginPage(pdfContext, &box);
    	//CGContextSaveGState(pdfContext);
    	//CGContextClipToRect(pdfContext, box);
    	
    	for(int i=0; i<pageNumbers; i++)
    	{
    		NSURL *pdfURL = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"test2" ofType:@"pdf"]];
    		
    		CGPDFDocumentRef pdf = CGPDFDocumentCreateWithURL((CFURLRef)pdfURL);
    		CGPDFPageRef currentPDFPage = CGPDFDocumentGetPage(pdf, i+1);
    		
    		CGRect pageMediaBox = CGPDFPageGetBoxRect(currentPDFPage, kCGPDFMediaBox);
    		
    		//CGContextTranslateCTM(pdfContext, 0.0, i*pageMediaBox.size.height);
    		
    		//CGContextScaleCTM(pdfContext, 1.0, -1.0);
    		
    		CGContextSaveGState(pdfContext);
    		CGRect drawRect = CGRectMake(0, i * pageMediaBox.size.height, pageMediaBox.size.width, pageMediaBox.size.height);
    		CGAffineTransform pdfTransform = CGPDFPageGetDrawingTransform(currentPDFPage, kCGPDFMediaBox, drawRect, 0, true);
    		
    		CGContextConcatCTM(pdfContext, pdfTransform);
    		
    		CGContextDrawPDFPage(pdfContext, currentPDFPage);
    		
    		CGContextRestoreGState(pdfContext);
    	}
    	
    	//CGContextRestoreGState(pdfContext);
    	CGContextEndPage(pdfContext);
    	CGContextRelease(pdfContext);
    }
    
     

    Attached Files:

  6. Psvetly macrumors newbie

    Joined:
    Jun 7, 2010
    #6
    Good time.

    is the problem solved? Having the same issue with fonts while saving one PDF from another via CGContextDrawPDFPage.

    Will appreciate any help!
     

Share This Page