views:

631

answers:

5

Here is the code:

http://dl.dropbox.com/u/5391413/PDFScroller.zip

I took the WWDC 2010 PhotoScroller sample code that implements nested UIScrollViews for zooming, inside a UIScrollView for paging, and swapped out what I thought would be minimal amount of code required for displaying a multi-page PDF instead of images.

It works. But it's slow on my iPhone4, about three seconds to paint the first page, and even slower on my iPod Touch. I can watch it painting the individual tiles. This same PDF already opens up more quickly, with no visible tile drawing, in an alternate CATiledLayer implementation I have which simply uses a single CATiledLayer/UIScrollView and touch events to change pages. I'd like to use this PhotoScroller technique, it's very nice.

I watched it with CPU Sampler in Instruments, and it doesn't seem to be the PDF rendering code, it looks like the time is taken up in threading and messaging. I'd appreciate it if someone could help point out what this sample is doing to incur the overhead.

Thanks,

Jim


Update 1: I had originally used the TilingView class technique from the sample code of defining

+ (Class) layerClass {
  return [CATiledLayer class];
}

And then drawing in - (void)drawRect:(CGRect)rect but switched to the explicit CATiledLayer subclass as a first attempt at seeing whether it would make a difference, but it did not, and so I left the code as-is for posting here. There is also a missing [tiledLayer release]; leak in TilingView.

A: 

Hi jbm,

as your code contains couple of errors and i can not compile the code, but i took a look at the PDF file which was included in the archive and i know the reason why your TilingView is slow.

Normally when you draw a pdf page in a CGContext using the method CGContextDrawPDFPage:, all text and vectorial graphics were rendered and other things like normal graphics in the PDF are just get drawn and cached. So it does not matter how big the PDF file is, but it does matter if you have vectorial grahics in your PDF. It seems that you have some vectorial graphic in your PDF and also some math equations, that's the reason why it is slow. I suggest you to try with another PDF file which does not contain vectorial graphics and see if it is faster.

Cheers

Zheng

Zheng, thanks for your response. On my computer the code builds and runs with the latest iOS 4.0.2 SDK. And as far as the content of the PDF file goes, unfortunately, I don't get to choose which PDF my users decide to try to view, I must simply do my best with any valid PDF document.
jbm
A: 

Conjecture not to be taken with any sort of authority: PDF is a vector based format for most documents (excluding those that simply serve as a container for embedded TIFF images). So when you tile the PDF like the PhotoScroller, you essentially ask the phone to scale and rasterize the whole PDF (well at least the given page) for each individual tile. So rather than painting it once as you might for a single CATiledLayer, you do it multiple times for each resolution. Since the PDF is a scalable format in itself, you should be able to simply render the entire view once for each page/scale.

Update: Having just gone through this myself, the PhotoScroller sample has some logic issues that make it very slow. Basically it renders the each tile at 1/zoomScale then scales is back down to zoomScale. So if zoom is at .5 it renders at 2x then scales that back down to 0.5x. Very slow an inefficient.

Paul Alexander
Agreed, and the CATiledLayer should be taking care of that for you, right? It would be nice to have some diagnostic output, or even a delegate API from that class to let us know how the caching behaves, according to the properties we set: tile size, detail, detail bias. I suppose they need room to tweak the algorithm.
jbm
A: 

Hi Jbm,

I tried your PDF scrolling code. It works great when tilesize property is increased.

Individually the project works great. However when I copied these 3 files in my another project and called the PhotoViewController on a button click, The PDF page goes on shifting to right with each swipe. It means that first page is at the correct position. but the 2nd page is shifted right and this goes on. So after 9 to 10 pages only blank screen is seen.

Why is this happening when I am using the exact same files? I tried with and without navigation bar but it does not have any effect. Please help me in this regard. Can you please answer this.

http://stackoverflow.com/questions/3854508/in-photoscroller-app-iphone-wwdc-104-photos-app-uiscrollview-images-shift-to-ri

Also how to load any particular page as starting point (depending on user selection) ?

I know it's not an answer but I wrote here because the question is related to your App. Thanks in advance.

Roger_iPhone
+1  A: 

See this Thread http://stackoverflow.com/questions/3889634/fast-and-lean-pdf-viewer-how-does-ibooks-do-it for PDF rendering tips.

Luke Mcneice