CatNiP prefinal
Sähköinen nuottikirja, HY-TKTKL-OHTUPROJ KESÄ11
/Users/awniemel/Notepad-SVN/svn/trunk/CatNiP/CatNiP/UIDocumentPDF.m
Go to the documentation of this file.
00001 
00002 
00003 
00004 
00005 
00006 
00007 #import "UIDocumentPDF.h"
00008 
00009 @implementation UIDocumentPDF
00010 
00011 @synthesize CGPDFDocument = document;
00012 @synthesize box;
00013 
00016 static const int MAX_PAGE_WIDTH = 2 * 768;
00017 
00026 + (UIDocumentPDF *)documentWithCGPDFDocument:(CGPDFDocumentRef)CGPDFDocument
00027 {
00028     return [[[UIDocumentPDF alloc] initWithCGPDFDocument:CGPDFDocument] autorelease];
00029 }
00030 
00040 - (id)init
00041 {
00042     box = kCGPDFMediaBox;
00043     return self;
00044 }
00045 
00053 - (id)initWithCGPDFDocument:(CGPDFDocumentRef)CGPDFDocument
00054 {
00055     self = [self init];
00056     if(CGPDFDocument != NULL) {
00057         document      = CGPDFDocumentRetain(CGPDFDocument);
00058         numberOfPages = CGPDFDocumentGetNumberOfPages(CGPDFDocument);
00059         
00060         // Loop through the pages and calculate the document dimensions: the
00061         // maximum of the width of the pages and the sum of their heights.
00062         for(int i = 1; i <= numberOfPages; ++i) {
00063             CGSize pageSize = [self getSizeOfPage:i];
00064             size.width   = pageSize.width > size.width ? pageSize.width : size.width;
00065             size.height += pageSize.height;
00066         }
00067         
00068         return self;
00069     }
00070     return nil;
00071 }
00072 
00080 - (id)initWithContentsOfFile:(NSString *)path
00081 {
00082         if(path != nil) {
00083         NSURL* url = [[NSURL alloc] initFileURLWithPath:path];
00084         CGPDFDocumentRef pdf = CGPDFDocumentCreateWithURL((CFURLRef)url);
00085         
00086         self = [self initWithCGPDFDocument:pdf];
00087         
00088         CGPDFDocumentRelease(pdf);
00089         [url release];
00090         
00091         return self;
00092     }
00093     return nil;
00094 }
00095 
00102 - (id)initWithData:(NSData *)data
00103 {
00104     // No need to check for data validity¸ CGDataProviderCreateWithCFData
00105     // returns nil properly on failure.
00106     
00107     CGDataProviderRef provider = CGDataProviderCreateWithCFData((CFDataRef)data);
00108     CGPDFDocumentRef pdf = CGPDFDocumentCreateWithProvider(provider);
00109     
00110     self = [self initWithCGPDFDocument:pdf];
00111     
00112     CGPDFDocumentRelease(pdf);
00113     CGDataProviderRelease(provider);
00114     
00115     return self;
00116 }
00117 
00125 - (UIImage *)getImageOfPage:(int)pageNumber
00126 {
00127     // PDF internal page coordinates place the origo in the bottom left corner
00128     // of the page, so the drawing needs to be flipped vertically; hence the
00129     // curious negative signs in the CGRectMake and CGContextScaleCTM calls.
00130     
00131 #if DEBUG
00132     NSLog(@"Started loading page %d",pageNumber);
00133 #endif
00134     
00135     CGPDFPageRef page = CGPDFDocumentGetPage(document, pageNumber);
00136     
00137     CGSize pageSize = [self getSizeOfPage:pageNumber];
00138     CGRect pageRect = CGRectMake(0, 0, pageSize.width, -pageSize.height);
00139     
00140     UIGraphicsBeginImageContext(pageSize);
00141     CGContextRef context = UIGraphicsGetCurrentContext();
00142     
00143     CGAffineTransform transform = CGPDFPageGetDrawingTransform(page, box, pageRect, 0, YES);
00144     CGContextScaleCTM(context, 1.0, -1.0);
00145     CGContextConcatCTM(context, transform);
00146     
00147     CGContextDrawPDFPage(context, page);
00148     
00149     UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
00150     UIGraphicsEndImageContext();
00151     
00152 #if DEBUG
00153     NSLog(@"Page %d loaded to memory",pageNumber);
00154 #endif
00155     
00156     return image;
00157 }
00158 
00165 - (CGSize)getSizeOfPage:(int)pageNumber
00166 {
00167     CGPDFPageRef page = CGPDFDocumentGetPage(document, pageNumber);
00168     CGRect boxRect    = CGPDFPageGetBoxRect(page, box);
00169     int rotationAngle = CGPDFPageGetRotationAngle(page);
00170     
00171     CGSize pageSize;
00172     
00173     // Fix size if page is portrait-oriented
00174     if(rotationAngle % 180 == 0)
00175         pageSize = CGSizeMake(boxRect.size.width, boxRect.size.height);
00176     else
00177         pageSize = CGSizeMake(boxRect.size.height, boxRect.size.width);
00178     
00179     // Downscale size to conserve processor cycles in case the page is drawn
00180     if(pageSize.width > MAX_PAGE_WIDTH) {
00181         CGFloat ratio = MAX_PAGE_WIDTH / pageSize.width;
00182         pageSize.width  *= ratio;
00183         pageSize.height *= ratio;
00184     }
00185     
00186     return pageSize;
00187 }
00188 
00189 - (void)dealloc
00190 {
00191     CGPDFDocumentRelease(document);
00192     [super dealloc];
00193 }
00194 
00195 @end
 All Classes Files Functions Variables Enumerations Enumerator Properties Defines