From e7c259cafdf934ee98c208abeaed8e0ca52190ac Mon Sep 17 00:00:00 2001 From: Paul Gardiner Date: Tue, 22 Apr 2014 12:43:05 +0100 Subject: iOS: refactor AirPrint code ready for printing at higher res and in strips --- platform/ios/Classes/MuPrintPageRenderer.m | 142 +++++++++++++++++++++++------ 1 file changed, 113 insertions(+), 29 deletions(-) (limited to 'platform/ios/Classes') diff --git a/platform/ios/Classes/MuPrintPageRenderer.m b/platform/ios/Classes/MuPrintPageRenderer.m index 0ab74c79..919145fd 100644 --- a/platform/ios/Classes/MuPrintPageRenderer.m +++ b/platform/ios/Classes/MuPrintPageRenderer.m @@ -32,59 +32,143 @@ return npages; } --(void) drawPageAtIndex:(NSInteger)pageIndex inRect:(CGRect)printableRect +static fz_page *getPage(fz_document *doc, int pageIndex) { - CGContextRef cgctx = UIGraphicsGetCurrentContext(); + __block fz_page *page = NULL; - if (!cgctx) return; + dispatch_sync(queue, ^{ + fz_try(ctx) + { + page = fz_load_page(doc, pageIndex); + } + fz_catch(ctx) + { + printf("Failed to load page\n"); + } + }); - CGSize paperSize = self.paperRect.size; - // We must perform mupdf calls within this function, but all library calls need - // to be on our background thread, so we run them synchronously on the queue + 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; - __block CGSize pageSize; + + 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_page *page = NULL; fz_device *dev = NULL; - fz_var(page); fz_var(dev); fz_try(ctx) { - fz_rect bounds; - fz_matrix ctm; - page = fz_load_page(docRef->doc, pageIndex); - fz_bound_page(docRef->doc, page, &bounds); - pageSize.width = bounds.x1 - bounds.x0; - pageSize.height = bounds.y1 - bounds.y0; - CGSize scale = fitPageToScreen(pageSize, paperSize); - pageSize.width = roundf(pageSize.width * scale.width); - pageSize.height = roundf(pageSize.height * scale.height); - // Need to render upside down. No idea why. - fz_scale(&ctm, scale.width, -scale.height); - fz_pre_translate(&ctm, 0, -pageSize.height); - pix = fz_new_pixmap(ctx, fz_device_rgb(ctx), pageSize.width, pageSize.height); - fz_clear_pixmap_with_value(ctx, pix, 255); dev = fz_new_draw_device(ctx, pix); - fz_run_page(docRef->doc, page, dev, &ctm, NULL); + fz_clear_pixmap_with_value(ctx, pix, 0xFF); + fz_run_page(doc, page, dev, ctm, NULL); } fz_always(ctx) { - fz_free_page(docRef->doc, page); fz_free_device(dev); } fz_catch(ctx) { - printf("Failed to print page %d\n", pageIndex+1); + 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(); + + 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 = roundf(pageSize.width * scale.width); + pageSize.height = roundf(pageSize.height *scale.height); + + pix = createPixMap(pageSize); + if (!pix) + goto exit; - if (!pix) return; + 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, -scale.height); + fz_pre_translate(&ctm, 0, -pageSize.height); + + renderPage(docRef->doc, page, pix, &ctm); CGRect rect = {{0.0,0.0},pageSize}; - CGDataProviderRef dataref = wrapPixmap(pix); - CGImageRef img = newCGImageWithPixmap(pix, dataref); CGContextDrawImage(cgctx, rect, img); + +exit: + freePage(docRef->doc, page); CGImageRelease(img); CGDataProviderRelease(dataref); //releases pix } -- cgit v1.2.3