summaryrefslogtreecommitdiff
path: root/platform/ios/Classes/MuPrintPageRenderer.m
blob: 0ab74c798bd29a6c63faa06f5a74f8de4f024e51 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
#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;
}

-(void) drawPageAtIndex:(NSInteger)pageIndex inRect:(CGRect)printableRect
{
	CGContextRef cgctx = UIGraphicsGetCurrentContext();

	if (!cgctx) return;

	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

	__block fz_pixmap *pix = NULL;
	__block CGSize pageSize;
	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_always(ctx)
		{
			fz_free_page(docRef->doc, page);
			fz_free_device(dev);
		}
		fz_catch(ctx)
		{
			printf("Failed to print page %d\n", pageIndex+1);
		}
	});

	if (!pix) return;

	CGRect rect = {{0.0,0.0},pageSize};
	CGDataProviderRef dataref = wrapPixmap(pix);
	CGImageRef img = newCGImageWithPixmap(pix, dataref);
	CGContextDrawImage(cgctx, rect, img);
	CGImageRelease(img);
	CGDataProviderRelease(dataref); //releases pix
}

@end