Hi there,
I have two questions related to handling PDF rendering on iPad/iPhone.
First
I'm getting some strange issues when rendering PDF page with CGPDF functions on iPad. Strange, because everything works quite fine on iPhone, but on iPad I'm getting lots of error messages related to PDF, i.e. like below
invalid stream length 9785; endstream not found.
FlateDecode: decoding error: incorrect header check.
invalid function: failed to read 765 bytes.
stack underflow: popping past mark.
missing or invalid arguments for color operator.
FlateDecode: decoding error: incorrect header check.
FlateDecode: decoding error.
<Error>: FT_Open_Face failed: error 2.
<Error>: FT_Open_Face failed: error 85.
encountered unexpected object type: 7.
missing or invalid object number.
invalid image `ColorSpace' value.
unexpected symbol `obj' while reading object.
invalid descendant font for Type0 font.
font `F28' not found in document.
<Error>: FT_Outline_Decompose failed: error 20.
font `R222' not found in document.
...and many others. I understand that it's maybe a problem of wrong PDF structure, but I don't understand why I can see all those errors only on iPad while on iPhone there's just a small number of them compared to iPad and in most cases page is displayed correctly despite of reported errors, which, again, is not true on iPad.
Is there some difference in Quartz implementations in iPhoneOS 3.2 and 3.1/4.0? And are there some guidelines about PDF format readable on iPhone/iPad?
Second:
Another issue is with creating bitmap context for different page sizes. I need to render the same PDF page for portrait as well as landscape orientations. But while it works for portrait (both on iPhone), it does not for landscape on iPad, throwing following error:
CGBitmapContextCreate: unsupported parameter combination: 8 integer bits/component; 32 bits/pixel; 3-component colorspace; kCGImageAlphaPremultipliedLast; 4095 bytes/row.
The code used to create the context is like following:
/// Calculate memory block size needed
int bytesPerRow = (int)((int)_pageSize.width * 4);
int dataSize = (int)(bytesPerRow * _pageSize.height);
/// Allocate memory; As noted in docs, on iOS 4 it can be NULL, but as mentioned
/// below: Do not pass NULL if you are running on earlier operating systems.
/// So don't pass NULL...
void *bitmapData = malloc(dataSize);
if(!bitmapData) {
/// Hm, out of memory?
return NULL;
}
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
CGContextRef context = CGBitmapContextCreate(bitmapData,
_pageSize.width,
_pageSize.height,
8, /* bits per component*/
bytesPerRow, /* bytes per row */
colorSpace,
kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big);
CGColorSpaceRelease(colorSpace);
if(!context) {
/// Something is really wrong!
free(bitmapData);
bitmapData = NULL;
return NULL;
}
CGContextClipToRect(context, CGRectMake(0, 0, _pageSize.width, _pageSize.height));
/// Ask data source to render contents
[_dataSource renderPageAtIndex: pageIndex inContext: context];
/// Get bitmap image from context
CGImageRef image = CGBitmapContextCreateImage(context);
/// Free context AND previously allocated block of data
CGContextRelease(context);
free(bitmapData);
bitmapData = NULL;
/// Finish operation...
As I said, it works fine under iPhone and works for portrait orientation on iPad, it does not for landscape on iPad. The only difference is really the current page size supplied. However, page size here is not equal to screen size in landscape mode (1024x768), but it's size calculated to fit screen width, allowing user to scroll vertically to see complete page. Typically, page size on iPad is 1024x1403 (depends on PDF format).
I don't understand why the code above does not work for bigger page sizes.
Any idea, please? Thanks.