#include "common.h" #import "MuPrintPageRenderer.h" @implementation MuPrintPageRenderer -(id) initWithDocRef:(MuDocRef *)aDocRef { self = [super init]; if (self) { docRef = [aDocRef retain]; } return self; } -(void) dealloc { [docRef release]; [super dealloc]; } -(NSInteger) numberOfPages { __block NSInteger npages = 0; dispatch_sync(queue, ^{ fz_try(ctx) { npages = fz_count_pages(docRef->doc); } fz_catch(ctx); }); return npages; } static fz_page *getPage(fz_document *doc, int pageIndex) { __block fz_page *page = NULL; dispatch_sync(queue, ^{ fz_try(ctx) { page = fz_load_page(doc, pageIndex); } fz_catch(ctx) { printf("Failed to load page\n"); } }); return page; } static CGSize getPageSize(fz_document *doc, fz_page *page) { __block CGSize size = {0.0,0.0}; dispatch_sync(queue, ^{ fz_try(ctx) { fz_rect bounds; fz_bound_page(doc, page, &bounds); size.width = bounds.x1 - bounds.x0; size.height = bounds.y1 - bounds.y0; } fz_catch(ctx) { printf("Failed to find page bounds\n"); } }); return size; } static fz_pixmap *createPixMap(CGSize size) { __block fz_pixmap *pix = NULL; dispatch_sync(queue, ^{ fz_try(ctx) { pix = fz_new_pixmap(ctx, fz_device_rgb(ctx), size.width, size.height); } fz_catch(ctx) { printf("Failed to create pixmap\n"); } }); return pix; } static void freePage(fz_document *doc, fz_page *page) { dispatch_sync(queue, ^{ fz_free_page(doc, page); }); } static void dropPixmap(fz_pixmap *pix) { dispatch_sync(queue, ^{ fz_drop_pixmap(ctx, pix); }); } static void renderPage(fz_document *doc, fz_page *page, fz_pixmap *pix, fz_matrix *ctm) { dispatch_sync(queue, ^{ fz_device *dev = NULL; fz_var(dev); fz_try(ctx) { dev = fz_new_draw_device(ctx, pix); fz_clear_pixmap_with_value(ctx, pix, 0xFF); fz_run_page(doc, page, dev, ctm, NULL); } fz_always(ctx) { fz_free_device(dev); } fz_catch(ctx) { printf("Failed to render page\n"); } }); } -(void) drawPageAtIndex:(NSInteger)pageIndex inRect:(CGRect)printableRect { fz_page *page = NULL; fz_pixmap *pix = NULL; CGDataProviderRef dataref = NULL; CGImageRef img = NULL; CGContextRef cgctx = UIGraphicsGetCurrentContext(); float dpi = 300.0; float ppi = 72.0; if (!cgctx) return; CGSize paperSize = self.paperRect.size; page = getPage(docRef->doc, pageIndex); if (page == NULL) return; CGSize pageSize = getPageSize(docRef->doc, page); if (pageSize.width == 0.0 || pageSize.height == 0.0) goto exit; CGSize scale = fitPageToScreen(pageSize, paperSize); pageSize.width *= scale.width; pageSize.height *= scale.height; CGSize pageSizePix = {roundf(pageSize.width * dpi / ppi), roundf(pageSize.height * dpi /ppi)}; pix = createPixMap(pageSizePix); if (!pix) goto exit; dataref = wrapPixmap(pix); if (dataref == NULL) goto exit; img = newCGImageWithPixmap(pix, dataref); if (img == NULL) goto exit; fz_matrix ctm; fz_scale(&ctm, scale.width * dpi / ppi, -scale.height * dpi / ppi); fz_pre_translate(&ctm, 0, -pageSize.height); renderPage(docRef->doc, page, pix, &ctm); CGRect rect = {{0.0,0.0},pageSize}; CGContextDrawImage(cgctx, rect, img); exit: freePage(docRef->doc, page); CGImageRelease(img); CGDataProviderRelease(dataref); //releases pix } @end