views:

366

answers:

2

I'm using CATiledLayer to render a heavy pdf page inside a UIScrollView that is used to handle zooming and spanning..

The method below is called every time a Tile need to be drawn and I regret that I have to paint the whole pdf every time. I hope that behind the scene the CATiledLayer only render the part that it needs but nothing is less sure at the moment.

- (void)drawLayer: (CALayer*)layer inContext: (CGContextRef) context {
    [super drawLayer:layer inContext:context];      

    CGRect box = CGContextGetClipBoundingBox(context);

    CGContextSetGrayFillColor(context, 1.0, 1.0);
    CGContextFillRect(context, box);
    CGContextTranslateCTM(context, 0.0, self.bounds.size.height);
    CGContextScaleCTM(context, 1.0, -1.0);
    CGContextConcatCTM(context, CGPDFPageGetDrawingTransform(pdfPage, kCGPDFCropBox, layer.bounds, 0, true));
    CGContextDrawPDFPage(context, pdfPage);     
}

I can determine the Tile coordinate using following code

 CATiledLayer* castedLayer = (CATiledLayer*)layer;
 CGSize tileSize = [castedLayer tileSize];
 CGRect box = CGContextGetClipBoundingBox(context);
 CGFloat x = box.origin.x / tileSize.width;
 CGFloat y = box.origin.y / tileSize.height;    

but can't find a way to only render the part of the pdf that is usefull for that Tile

Could someone either explain how I can render only the part of the pdf that I need or explain why it is not necessary on a performance point of view.

A: 

I think you will be interesting to see an example of using a CATiledLayer to present a large, zoomable PDF in a UIScrollView: Simple UIScrollView / CATiledLayer PDF Example

MeGr
That's the kind of code I'm doing now. My concern is that the CGContextDrawPDFPage call is made for each and every tile in the view. That make 1 call for 1024/1024 tiles in zoom level 1 but 4 calls for zoom level 2 and 16 calls for zoom level 3 ! Each time a Clip is made so the method does not draw outside that clip but it is till make the document to be parse completely and every draw method to be called.
VdesmedT
A: 

Until now, I haven't found any way to draw only a part of a pdf. And I understand why since I asked. The way pdf files are made makes very difficult (practically impossible) to predict what needs to be drawn on a particular rect except maybe for pictures which position and size are described in the pdf.

On the other hand, since the context received in the drawLayer:inContext method come pre configured with a clip defined for the tile being drawn, the CGOperation used by the CGDrawPDFPage method are probably much faster since they don't have to actually draw anything if not in the clip defined on the context.

I then guess that the performance issue is not that bad and I could figure it out by calculating the time spent in the drawLayer:inContext method and figure out that not every tiles took the same time to render. I guessed that complex tiles (lot of graphics) took longer.

VdesmedT