summaryrefslogtreecommitdiff
path: root/platform/ios/Classes
diff options
context:
space:
mode:
authorPaul Gardiner <paul.gardiner@artifex.com>2013-10-14 12:54:10 +0100
committerPaul Gardiner <paul.gardiner@artifex.com>2013-10-16 09:59:36 +0100
commit566c82a6b6d21fe06985b98346369329c101c88e (patch)
treef2a88f42200232d6f9c19bb29cab519b589ac264 /platform/ios/Classes
parentf9456a8ea13a63989b9c948fa93f474db3ca59b5 (diff)
downloadmupdf-566c82a6b6d21fe06985b98346369329c101c88e.tar.xz
iOS: use partial updates to display annotation changes
Diffstat (limited to 'platform/ios/Classes')
-rw-r--r--platform/ios/Classes/MuPageViewNormal.m184
1 files changed, 165 insertions, 19 deletions
diff --git a/platform/ios/Classes/MuPageViewNormal.m b/platform/ios/Classes/MuPageViewNormal.m
index 49df6c38..a342ae8e 100644
--- a/platform/ios/Classes/MuPageViewNormal.m
+++ b/platform/ios/Classes/MuPageViewNormal.m
@@ -16,7 +16,9 @@ static void releasePixmap(void *info, const void *data, size_t size)
fz_drop_pixmap(ctx, info);
});
else
+ {
fz_drop_pixmap(ctx, info);
+ }
}
static CGDataProviderRef wrapPixmap(fz_pixmap *pix)
@@ -147,7 +149,7 @@ static fz_display_list *create_annot_list(fz_document *doc, fz_page *page)
return list;
}
-static fz_pixmap *renderPage(fz_document *doc, fz_display_list *page_list, fz_display_list *annot_list, CGSize pageSize, CGSize screenSize, CGRect tileRect, float zoom)
+static fz_pixmap *renderPixmap(fz_document *doc, fz_display_list *page_list, fz_display_list *annot_list, CGSize pageSize, CGSize screenSize, CGRect tileRect, float zoom)
{
fz_irect bbox;
fz_rect rect;
@@ -196,6 +198,112 @@ static fz_pixmap *renderPage(fz_document *doc, fz_display_list *page_list, fz_di
return pix;
}
+typedef struct rect_list_s rect_list;
+
+struct rect_list_s
+{
+ fz_rect rect;
+ rect_list *next;
+};
+
+static void drop_list(rect_list *list)
+{
+ while (list)
+ {
+ rect_list *n = list->next;
+ fz_free(ctx, list);
+ list = n;
+ }
+}
+
+static rect_list *updatePage(fz_document *doc, fz_page *page)
+{
+ rect_list *list = NULL;
+
+ fz_var(list);
+ fz_try(ctx)
+ {
+ pdf_document *idoc = pdf_specifics(doc);
+
+ if (idoc)
+ {
+ fz_annot *annot;
+
+ pdf_update_page(idoc, (pdf_page *)page);
+ while ((annot = (fz_annot *)pdf_poll_changed_annot(idoc, (pdf_page *)page)) != NULL)
+ {
+ rect_list *node = fz_malloc_struct(ctx, rect_list);
+
+ fz_bound_annot(doc, annot, &node->rect);
+ node->next = list;
+ list = node;
+ }
+ }
+ }
+ fz_catch(ctx)
+ {
+ drop_list(list);
+ list = NULL;
+ }
+
+ return list;
+}
+
+static void updatePixmap(fz_document *doc, fz_display_list *page_list, fz_display_list *annot_list, fz_pixmap *pixmap, rect_list *rlist, CGSize pageSize, CGSize screenSize, CGRect tileRect, float zoom)
+{
+ fz_irect bbox;
+ fz_rect rect;
+ fz_matrix ctm;
+ fz_device *dev = NULL;
+ CGSize scale;
+
+ screenSize.width *= screenScale;
+ screenSize.height *= screenScale;
+ tileRect.origin.x *= screenScale;
+ tileRect.origin.y *= screenScale;
+ tileRect.size.width *= screenScale;
+ tileRect.size.height *= screenScale;
+
+ scale = fitPageToScreen(pageSize, screenSize);
+ fz_scale(&ctm, scale.width * zoom, scale.height * zoom);
+
+ bbox.x0 = tileRect.origin.x;
+ bbox.y0 = tileRect.origin.y;
+ bbox.x1 = tileRect.origin.x + tileRect.size.width;
+ bbox.y1 = tileRect.origin.y + tileRect.size.height;
+ fz_rect_from_irect(&rect, &bbox);
+
+ fz_var(dev);
+ fz_try(ctx)
+ {
+ while (rlist)
+ {
+ fz_irect abox;
+ fz_rect arect = rlist->rect;
+ fz_transform_rect(&arect, &ctm);
+ fz_intersect_rect(&arect, &rect);
+ fz_round_rect(&abox, &arect);
+ if (!fz_is_empty_irect(&abox))
+ {
+ fz_clear_pixmap_rect_with_value(ctx, pixmap, 255, &abox);
+ dev = fz_new_draw_device_with_bbox(ctx, pixmap, &abox);
+ fz_run_display_list(page_list, dev, &ctm, &arect, NULL);
+ fz_run_display_list(annot_list, dev, &ctm, &arect, NULL);
+ fz_free_device(dev);
+ dev = NULL;
+ }
+ rlist = rlist->next;
+ }
+ }
+ fz_always(ctx)
+ {
+ fz_free_device(dev);
+ }
+ fz_catch(ctx)
+ {
+ }
+}
+
#import "MuPageViewNormal.h"
@implementation MuPageViewNormal
@@ -389,7 +497,7 @@ static fz_pixmap *renderPage(fz_document *doc, fz_display_list *page_list, fz_di
[self ensureDisplaylists];
CGSize scale = fitPageToScreen(pageSize, self.bounds.size);
CGRect rect = (CGRect){{0.0, 0.0},{pageSize.width * scale.width, pageSize.height * scale.height}};
- image_pix = renderPage(doc, page_list, annot_list, pageSize, self.bounds.size, rect, 1.0);
+ image_pix = renderPixmap(doc, page_list, annot_list, pageSize, self.bounds.size, rect, 1.0);
CGDataProviderRelease(imageData);
imageData = wrapPixmap(image_pix);
UIImage *image = newImageWithPixmap(image_pix, imageData);
@@ -540,7 +648,7 @@ static fz_pixmap *renderPage(fz_document *doc, fz_display_list *page_list, fz_di
[self ensureDisplaylists];
printf("render tile\n");
- tile_pix = renderPage(doc, page_list, annot_list, pageSize, screenSize, viewFrame, scale);
+ tile_pix = renderPixmap(doc, page_list, annot_list, pageSize, screenSize, viewFrame, scale);
CGDataProviderRelease(tileData);
tileData = wrapPixmap(tile_pix);
UIImage *image = newImageWithPixmap(tile_pix, tileData);
@@ -548,8 +656,6 @@ static fz_pixmap *renderPage(fz_document *doc, fz_display_list *page_list, fz_di
dispatch_async(dispatch_get_main_queue(), ^{
isValid = CGRectEqualToRect(frame, tileFrame) && scale == tileScale;
if (isValid) {
- tileFrame = CGRectZero;
- tileScale = 1;
if (tileView) {
[tileView removeFromSuperview];
[tileView release];
@@ -605,24 +711,59 @@ static fz_pixmap *renderPage(fz_document *doc, fz_display_list *page_list, fz_di
- (void) setScale:(float)scale {}
+- (void) updatePageAndTileWithTileFrame:(CGRect)tframe tileScale:(float)tscale viewFrame:(CGRect)vframe
+{
+ rect_list *rlist = updatePage(doc, page);
+ fz_drop_display_list(ctx, annot_list);
+ annot_list = create_annot_list(doc, page);
+ if (tile_pix)
+ {
+ updatePixmap(doc, page_list, annot_list, tile_pix, rlist, pageSize, self.bounds.size, vframe, tscale);
+ UIImage *timage = newImageWithPixmap(tile_pix, tileData);
+ dispatch_async(dispatch_get_main_queue(), ^{
+ BOOL isValid = CGRectEqualToRect(tframe, tileFrame) && tscale == tileScale;
+ if (isValid)
+ [tileView setImage:timage];
+ [timage release];
+ });
+ }
+ CGSize fscale = fitPageToScreen(pageSize, self.bounds.size);
+ CGRect rect = (CGRect){{0.0, 0.0},{pageSize.width * fscale.width, pageSize.height * fscale.height}};
+ updatePixmap(doc, page_list, annot_list, image_pix, rlist, pageSize, self.bounds.size, rect, 1.0);
+ drop_list(rlist);
+ UIImage *image = newImageWithPixmap(image_pix, imageData);
+ dispatch_async(dispatch_get_main_queue(), ^{
+ [imageView setImage:image];
+ [image release];
+ });
+}
+
- (void) invokeTextDialog:(NSString *)text
{
[dialogCreator invokeTextDialog:text okayAction:^(NSString *newText) {
+ CGRect tframe = tileFrame;
+ float tscale = tileScale;
+ CGRect vframe = tframe;
+ vframe.origin.x -= imageView.frame.origin.x;
+ vframe.origin.y -= imageView.frame.origin.y;
+
dispatch_async(queue, ^{
BOOL accepted = setFocussedWidgetText(doc, page, [newText UTF8String]);
- fz_drop_display_list(ctx, annot_list);
- annot_list = NULL;
- dispatch_async(dispatch_get_main_queue(), ^{
- if (accepted)
- [self loadPage];
- else
+ if (accepted)
+ {
+ [self updatePageAndTileWithTileFrame:tframe tileScale:tscale viewFrame:vframe];
+ }
+ else
+ {
+ dispatch_async(dispatch_get_main_queue(), ^{
[self invokeTextDialog:newText];
- });
+ });
+ }
});
}];
}
-- (void) passTapToPage:(CGPoint)pt
+- (int) passTapToPage:(CGPoint)pt
{
pdf_document *idoc = pdf_specifics(doc);
CGSize scale = fitPageToScreen(pageSize, self.bounds.size);
@@ -642,11 +783,6 @@ static fz_pixmap *renderPage(fz_document *doc, fz_display_list *page_list, fz_di
changed = pdf_pass_event(idoc, (pdf_page *)page, &event);
event.event.pointer.ptype = PDF_POINTER_UP;
changed |= pdf_pass_event(idoc, (pdf_page *)page, &event);
- if (changed)
- {
- fz_drop_display_list(ctx, annot_list);
- annot_list = NULL;
- }
focus = pdf_focused_widget(idoc);
if (focus)
@@ -679,6 +815,8 @@ static fz_pixmap *renderPage(fz_document *doc, fz_display_list *page_list, fz_di
fz_catch(ctx)
{
}
+
+ return changed;
}
- (MuTapResult *) handleTap:(CGPoint)pt
@@ -689,8 +827,16 @@ static fz_pixmap *renderPage(fz_document *doc, fz_display_list *page_list, fz_di
CGRect r = [[widgetRects objectAtIndex:i] CGRectValue];
if (CGRectContainsPoint([[widgetRects objectAtIndex:i] CGRectValue], ipt))
{
+ CGRect tframe = tileFrame;
+ float tscale = tileScale;
+ CGRect vframe = tframe;
+ vframe.origin.x -= imageView.frame.origin.x;
+ vframe.origin.y -= imageView.frame.origin.y;
+
dispatch_async(queue, ^{
- [self passTapToPage:ipt];
+ int changed = [self passTapToPage:ipt];
+ if (changed)
+ [self updatePageAndTileWithTileFrame:tframe tileScale:tscale viewFrame:vframe];
});
return [[[MuTapResultWidget alloc] init] autorelease];
}